Codeforces_356B_Xenia and Hamming(数论)

本文介绍了一种计算两字符串重复多次后形成的等长字符串间汉明距离的有效算法。通过分析字符串周期特性,利用最大公约数简化计算过程,避免了不必要的比较,显著提高了计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题型:数论


题意:

       汉明距离就是两个等长字符串之间的汉明距离是两个字符串对应位置的字符不同的个数,给出两个字符串S和T(不一定等长),给出求出n倍长的S和m倍长的T这两个字符串的汉明距离(加长的两个字符串等长)。


分析:

         一开始思路比较单纯,题目一看完就觉得比较出两个串的长度的最小公倍数长度的汉明距离,然后再扩大相应倍就可以了。但是这样显然是会TLE的,设S的长度为len1、T的长度为len2,如果len1和len2互质的话,复杂度就会达到O(len1*len2),最坏为10^12,过大。

         分析一下会发现,在上面的想法中,有一部分比较是没有必要的,比如:

                  S:  abacdcde                 T:  acdaed

         S的长度为8,T的长度为6,len1与len2的最小公倍数为24

         比较时                

                                                                         

          T开头的a并不是和S中的每一位都能进行比较的,也就是说,在一个循环结中,可以一次性将T中的每一位与其将会与S中所对应的位置的字符都比较一下,设g =gcd(len1,len2),设ans为S和T中对应位置相同的字符的数目,方法就是在i from 0 to gcd(len1,len2)-1 的循环中,将S分为g个小段,每段长度为len1/g,统计每次该小段上第i个字符出现的次数,然后将T中g个小段的第i个字符出现的次数加入到ans中。最后将ans扩大相应倍数,然后再用总的长度减去ans就是答案。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 1000010
using namespace std;
char s[MAXN],t[MAXN];

__int64 gcd(__int64 x, __int64 y){
 if (!x || !y) return x > y ? x : y;
 for (__int64 t; t = x % y; x = y, y = t);
 return y;
}

int main(){
    __int64 n,m;
    while(~scanf("%I64d%I64d",&n,&m)){
        scanf("%s%s",s,t);
        __int64 l1=strlen(s);
        __int64 l2=strlen(t);
        __int64 g=gcd(l1,l2);
        __int64 ans=0;

        for(int i=0;i<g;i++){
            __int64 cnt[26]={0},s_sub=l1/g,t_sub=l2/g;
            for(int j=0;j<s_sub;j++)
                cnt[s[g*j+i]-'a']++;
            for(int j=0;j<t_sub;j++)
                ans+=cnt[t[g*j+i]-'a'];
        }
        ans*=(m*g)/l1;
        ans=m*l2-ans;
        printf("%I64d\n",ans);
    }
    return 0;
}
/*
100 10
a
aaaaaaaaaa
1 1
abacaba
abzczzz
2 3
rzr
az
*/


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值