CF356B - Xenia and Hamming 题解

题目链接: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;
}
posted @ 2022-06-05 23:27  quanjun  阅读(24)  评论(0编辑  收藏  举报