CF356B Xenia and Hamming

这道题有个比较nice的思路。

设两个字符串长度的最小公倍数为lcm,最大公因数为gcd.

那么for(int i=0;i<len1;i++) vis[i%gcd][a[i]-'a']++;

for(int i=0;i<len2;i++) calc+=vis[i%gcd][b[i]-'a'];就能够统计lcm内相同的字符的个数,不同的就是lcm-calc;

在lcm内会跑完所有的gcd匹配情况,所以能够如此快速统计。细细感悟一下,,

比如说这里以4的红圈圈为例,那么它会依次匹配完6的红勾勾,然后完成匹配....tql

上代码:

 1 #include<bits/stdc++.h>
 2 #define maxn 1000005
 3 using namespace std;
 4 string a,b;
 5 typedef long long ll;
 6 ll n,m;
 7 ll gcd(ll x,ll y){
 8     if(y==0) return x;
 9     else return gcd(y,x%y);
10 }
11 ll vis[maxn][30];
12 void init(){
13     scanf("%lld%lld",&n,&m);
14     cin>>a;
15     cin>>b;
16     ll len1=a.length(),len2=b.length(); 
17     ll t=gcd(len1,len2);
18     ll lcm=len1*len2/t;
19     /*string c=a;
20     for(int i=1;i<t/len1;i++) a+=c;//粘贴 
21     c=b;
22     for(int i=1;i<t/len2;i++) b+=c;*///竟然会MLE
23     ll calc=0; 
24     for(int i=0;i<len1;i++) vis[i%t][a[i]-'a']++;
25     for(int i=0;i<len2;i++) calc+=vis[i%t][b[i]-'a'];
26     calc=lcm-calc; 
27     ll cnt=n/(lcm/len1);
28     printf("%lld",cnt*calc);
29 }
30 int main(){
31     init();
32     
33     return 0;
34 } 
原文地址:https://www.cnblogs.com/degage/p/9717241.html