Hdu 6863

Isomorphic Strings

题目大意:给你一个字符串,问你是否能将这个字符串分为k个相同地字符串,并且这k个字符串同构。

同构:如果将一个字符串的前几个字符按顺序移到后面,使得这个字符串和另一个字符串相同,那么这两个字符串同构

解题思路:hash来求解,求长度的每一个因子,然后可以将这个串分为若干个长度相同地字串。然后我们求得第一个字串的所有同构字串的hash值,判断剩下字串的hash值是否都包含在这个集合里即可

Hash:https://blog.csdn.net/nka_kun/article/details/81254013

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e7+7;
const int base=1331;
const int maxn=5e6+10;
int t,n;
char s[maxn];
int  p[maxn],a[maxn];
int jl[mod];
inline ll read(){
    ll s=0,w=1;char ch = getchar();
    while(ch<48 || ch>57) {
        if(ch=='-') w=-1;ch = getchar();
    }
    while(ch>=48&&ch<=57) s = (s<<1) + (s<<3) + (ch^48),ch=getchar();
    return s*w;
}
int js(int l,int r)
{
    return (a[r]-1ll*a[l-1]*p[r-l+1]%mod+mod)%mod;
}
int tot=0;
bool pd(int k,int id)
{
    if(k==1) return false;
    int len=n/k;
    int l=1,r=len;
    jl[js(1,len)]=id;
    for(int i=1;i<len;i++)
    {
        int temp1=(1ll*js(i+1,len)*p[i]%mod+js(1,i))%mod;
        jl[temp1]=id;
        
    }
    for(int i=1;i<=k;i++)
    {
        int temp=js(l,r);
        if(jl[temp]!=id) return  false;
        l+=len,r+=len;
    }
    return true;
}
int main()
{
    int t;
    t=read();
    p[0]=1;
    for(int  i=1;i<maxn;i++) p[i]=(1ll*p[i-1]*base)%mod;
    while(t--)
    {
        n=read();
        scanf("%s",s+1);
        for(int i=1;i<=n;i++) a[i]=(1ll*a[i-1]*base%mod+(s[i]-'a'+1))%mod;
        int flag=0;
        for(int i=1;1ll*i*i<=1ll*n&&!flag;i++)
        {
            if(n%i==0)
            {
                flag|=pd(i,tot++);
                flag|=pd(n/i,tot++);
            }
        }
        if(!flag) cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/tombraider-shadow/p/13503359.html