将n个字符串缩为一个字符串
————————————————————————————
借这个题学习一下double hash
还是需要好好练习的
KMP还是算了,没在计划中
————————————————————————————
#include<bits/stdc++.h> using namespace std; const int p1=1331,p2=13331,mod=1003020617; int pow1[1000100],pow2[1000100],la1[1000100],la2[1000100],nxt1[1000100],nxt2[1000100]; char ch[1000100],now[1000100]; int t,l=0; int check1(int cur) { int x1=nxt1[cur]; int x2=((la1[l]-1ll*la1[l-cur]*pow1[cur])%mod+mod)%mod; return x1==x2; } int check2(int cur) { int x1=nxt2[cur]; int x2=((la2[l]-1ll*la2[l-cur]*pow2[cur])%mod+mod)%mod; return x1==x2; } int main() { pow1[0]=pow2[0]=1; for(int i=1;i<=1000100;i++){pow1[i]=1ll*pow1[i-1]*p1%mod;pow2[i]=1ll*pow2[i-1]*p2%mod;} cin>>t; while(t--) { cin>>(now+1); int len=strlen(now+1),cur; for(int j=1;j<=len;j++) { nxt1[j]=(1ll*nxt1[j-1]*p1+now[j]-'0'+1)%mod; nxt2[j]=(1ll*nxt2[j-1]*p2+now[j]-'0'+1)%mod; } for(cur=len;cur;cur--) if(l>=cur&&check1(cur)&&check2(cur))break; for(int j=cur+1;j<=len;j++) { ch[++l]=now[j]; la1[l]=(1ll*la1[l-1]*p1+now[j]-'0'+1)%mod; la2[l]=(1ll*la2[l-1]*p2+now[j]-'0'+1)%mod; } } cout<<(ch+1); }