• Isomorphic Strings【字符串hash】-2020杭电多校8


    题意

    给一个字符串 (s) ,长度为 (n) ,问是否存在一个 (k) ,满足 (k∣n) ,将 (s) 分成相等的 (k) 段子串,每一段子串互为循环同构。其中,(1≤T≤1000,1≤n≤5⋅10^6, sum{n}leq2⋅10^7)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6863

    分析

    枚举 (n) 的所有满足条件的因子,然后对于每一个长度 (d),求出 ([1,d]) 的所有循环同构的字符串的 ( ext{Hash}) 值,进行标记,然后再遍历原字符串,求出划分后的其它所有子串是否满足循环同构。

    已知 ( ext{Hash[i]})( ext{Hash[j]}) ,其中 (i<j),求 ([i+1,j]) 子串的 ( ext{Hash}) 值:

    [ ext{ans}=( ext{Hash[j]}- ext{Hash[i]}· ext{base}^{j-i} \% mod+mod)\% mod ]

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int mod=12582917;
    const int N=5e6+6;
    const int maxn=2e7;
    const int base=1543;
    char ss[N];
    int Hash[N],por[N];
    int id[maxn],cnt;
    void init()
    {
        por[0]=1;
        for(int i=1;i<N;i++)
            por[i]=1LL*por[i-1]*base%mod;
    }
    void get_hash(int len)
    {
        for(int i=1;i<=len;i++)
            Hash[i]=(1LL*Hash[i-1]*base%mod+ss[i])%mod;
    }
    bool solve(int d,int len)
    {
        ++cnt;
        int tmp=Hash[d];
        id[tmp]=cnt;
        for(int i=1;i<=d;i++)//同构的其它串的hash值
        {
            tmp=(tmp-1LL*ss[i]*por[d-1]%mod+mod)%mod;
            tmp=(1LL*tmp*base+ss[i])%mod;
            id[tmp]=cnt;
        }
        for(int i=d+d;i<=len;i+=d)
        {
            int x=(Hash[i]-1LL*Hash[i-d]*por[d]%mod+mod)%mod;
            if(id[x]!=cnt) return false;
        }
        return true;
    }
    int main()
    {
        int T,n;
        init();
        scanf("%d",&T);
        cnt=0;
        while(T--)
        {
            scanf("%d",&n);
            scanf("%s",ss+1);
            get_hash(n);
            bool f=0;
            for(int i=2;i*i<=n;i++)//每一段的长度
            {
                if(n%i) continue;
                int t=n/i;
                f=solve(i,n);
                if(f) break;
                if(i!=t) f=solve(t,n);
                if(f) break;
            }
            if(f==0&&n>1) f=solve(1,n);
            if(f) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    【内推面试分享】普通本科的蚂蚁金服校招面试经验分享,内附答案
    Json解析
    创建新的MessageBox窗口前,先关掉之前已经创建好的
    TcxCheckComboBox的使用
    Delphi调用C#的DLL
    StringGrid数据导出到Excel
    从Excel导入信息在StringGrid显示
    JS的修饰符
    局部变量和全局变量
    List注意啊
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13501110.html
Copyright © 2020-2023  润新知