hdu 5782 Cycle(KMP+hash)

题目链接:hdu 5782 Cycle

题意:

给出两个字符串,判断他们每一个前缀是否循环同构,循环同构的意思就是,字符串首位相接拼成一个环,两个环通过旋转可以相等。

题解:

传送门

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 using namespace std;
 5 typedef unsigned long long ull;
 6 
 7 const int N=1e4+7;
 8 
 9 struct string_hash{
10     const static int seed=1331;
11     static ull b[N];
12     int len;ull h[N];
13     inline int idx(char x){return x-'a'+1;}
14     static void init(){b[0]=1;F(i,1,N-1)b[i]=b[i-1]*seed;}
15     void ins(char *s)
16     {
17         len=strlen(s+1);
18         F(i,1,len)h[i]=h[i-1]*seed+idx(s[i]);
19     }
20     inline ull ask(int l,int r){return h[r]-b[r-l+1]*h[l-1];}
21 }a[2];
22 ull string_hash::b[N];
23 
24 char sa[N],sb[N];
25 int nxt[N],ans[N];
26 
27 int check(int n,int m,int op)
28 {
29     if(n==m)return 1;
30     return a[op].ask(m+1,n)==a[op^1].ask(1,n-m);
31 }
32 
33 void KMP(int n, char*a, int m, char*b,int op) {
34     int i, j;
35     for (nxt[0] = j = -1, i = 1; i < n; nxt[i++] = j) {
36         while (~j&&a[j + 1] != a[i])j = nxt[j];
37         if (a[j + 1] == a[i])j++;
38     }
39     for (j = -1, i = 0; i < m; i++) {
40         while (~j&&a[j + 1] != b[i])j = nxt[j];
41         if (a[j + 1] == b[i])
42         {
43             j++;
44             if(!ans[i])ans[i]=check(i+1,j+1,op);
45         }
46         if (j == n - 1) j = nxt[j];
47     }
48 }
49 
50 int main(){
51     string_hash::init();
52     while(~scanf("%s%s",sa+1,sb+1))
53     {
54         a[0].ins(sa),a[1].ins(sb);
55         mst(ans,0);
56         KMP(a[0].len,sa+1,a[0].len,sb+1,0);
57         KMP(a[0].len,sb+1,a[0].len,sa+1,1);
58         ans[a[0].len+1]=0;
59         F(i,0,a[0].len-1)printf("%d",ans[i]);
60         puts("");
61     }
62     return 0;
63 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7211288.html