题目链接:https://codeforces.com/problemset/problem/356/B
题目大意:
字符串 \(a\) 是字符串 \(x\) 循环 \(n\) 次(\(a = \sum\limits_{n} x\)),
字符串 \(b\) 是字符串 \(y\) 循环 \(m\) 次(\(b = \sum\limits_{m} y\))。
字符串 \(a\) 和 \(b\) 长度相同,求字符串 \(a\) 和 \(b\) 存在多少个字符不相同。
解题思路(参考自:官方题解):
让我们定义第一个字符串 \(x\) 的长度为 \(lenX\),第二个字符串 \(y\) 的长度为 \(lenY\)。令 \(L = LCM(lenX, lenY)\)。很明显 \(L\) 是字符串 \(a\) 和 \(b\) 的一个循环节,所以我们可以计算两个字符串的长度为 \(L\) 的前缀的汉明距离,计算的结果再乘上 \(\frac{len(a)}{L}\) 就是最终的答案了。
对于字符串 \(x\) 中的任意位置 \(i\),我们可以思考 \(x\) 中的下标 \(i\) 能够对应 \(y\) 中的哪些下标 \(j\)。
很容易证明:若定义 \(g = GCD(lenX, lenY)\),则当 \(i \equiv j(\ mod \ g)\),则 \(x_i\) 将和 \(y_j\) 作比较。
对于任意一个位置除以 \(g\) 的余数,以及任意一个字符 \(c\) 我们可以计算得到 \(count(r, c)\),它在字符串 \(y\) 中存在多少个下标 \(j\) 满足 \(j \ mod \ g = r\) 且对应下标 \(j\) 对应的字符为 \(c\)。
当计算(前面长度为 \(L\) 的)汉明距离时,\(x_i\) 将和恰好 \(count(i \mod g, x_i)\) 个字符对应的位置相等且字符也相等,其余位置都是不相等的。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int cnt[maxn][26];
long long n, m, lenX, lenY, L, g, ans;
char x[maxn], y[maxn];
int main() {
scanf("%lld%lld%s%s", &n, &m, x, y);
lenX = strlen(x);
lenY = strlen(y);
g = __gcd(lenX, lenY);
L = lenX * lenY / g;
for (int i = 0; i < lenY; i++)
cnt[i%g][y[i]-'a']++;
ans = L;
for (int i = 0; i < lenX; i++)
ans -= cnt[i%g][x[i]-'a'];
printf("%lld\n", ans * (n * lenX / L));
return 0;
}