题意:给出一个n,m 然后给出两个串的循环节, n代表第一个串有多少次循环,m代表第二个串有多少次循环,问两个串的Hamming distance是多少,这个距离是指对应位置的字符如果相等对结果的贡献就是0,否者就是1.
思路:参考:传送门
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<utility>
#include<string>
using namespace std;
typedef long long ll;
const int qq = 1e6+10;
char a[qq],b[qq];
ll dpa[qq][27],dpb[qq][27];
ll gcd(ll a, ll b){
return b==0?a:gcd(b, a%b);
}
ll lcm(ll a, ll b){
return a/gcd(a, b)*b;
}
int main(){
ll n,m;scanf("%lld%lld",&n,&m);
scanf("%s%s",a,b);
ll lena = strlen(a);
ll lenb = strlen(b);
ll g = gcd(lena, lenb);
ll l = lena/g*lenb;
memset(dpa, 0, sizeof(dpa));
memset(dpb, 0, sizeof(dpb));
for(int i=0; i<lena; ++i) dpa[i%g][a[i]-'a']++;
for(int i=0; i<lenb; ++i) dpb[i%g][b[i]-'a']++;
ll ans = 0;
for(int i=0; i<g; ++i)
for(int j=0; j<26; ++j)
ans+=(ll)dpa[i][j]*dpb[i][j];
ans = n*lena/l*ans; //每一个长度为l的字符串中,所含相同的字符有ans个、
// 求长度为n*lena/l 个长度为l的字符串中,所含相同字符的总数、
ans = n*lena - ans; //求反面、 然后用总长度减去相同字符的个数、
printf("%lld\n", ans);
return 0;
}
这个具体我好像还不是太懂, 为什么分成g段之后比较每一个位置上相乘就能得到长度为l的结果、