一眼看成分段方式从前到后。
我们先考虑什么情况两个字符集拼出来地字符串会相同,容易发现是两个字符集全等。
这个东西可以用hash判定。
然后我们考虑怎么求出这个字符集。
每次\(n\%x\)这个块会向右走一个,那么会多一个块再少一个块,然后这个也可以字符串hash维护。
就做完了。之后重排列计数一下即可。时间复杂度是\(O(nlog^2n)\),一个是调和级数一个是map
但是这题的hash是真的毒瘤,我三模都没过,只能特判了。
code:
#include<bits/stdc++.h> #define I inline #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define abs(x) ((x)>0?(x):-(x)) #define re register #define ll long long #define db double #define N 600000 #define M 200 #define mod 998244353 #define eps (1e-7) #define U unsigned #define it iterator #define Gc() getchar() #define Me(x,y) memset(x,y,sizeof(x)) using namespace std; int n,m,Bh,cnt;char s[N+5];ll Ans,ToT,inv[N+5],pus;map<ll,int> Gs; I ll mpow(ll x,int y=mod-2){ll ans=1;while(y) (y&1)&&(ans=ans*x%mod),y>>=1,x=x*x%mod; return ans;} struct Hash_line{ U ll bas[N+5],pre[N+5];int i;const U ll G=19260817;//const ll Mod=1000000007; I void Make(){bas[0]=1;for(i=1;i<=n;i++) bas[i]=bas[i-1]*G,pre[i]=(pre[i-1]*G+s[i]);} I U ll Getline(int x,int y){return (pre[y]-pre[x-1]*bas[y-x+1]);} }H; struct Hash_table{ map<ll,int> Gs;ll Mod,ToT; I void MakeMod(ll x){Mod=x;} I ll mpow(ll x,ll y){ll ans=1;x%=Mod;while(y) (y&1)&&(ans=ans*x%Mod),y>>=1,x=x*x%Mod; return ans;} I ll Make(ll x){return mpow(x,7);} I void insert(ll x,int y){ToT=(Make(x)*y+ToT+Mod)%Mod;} I int Find(){return !Gs.count(ToT);} I void Get(){Gs[ToT]=1;} I void clear(){Gs.clear();ToT=0;} }A,B/*,C*/; I void clear(){ToT=1;cnt=0;Gs.clear();} I void insert(int x,int y){(~y)?(Gs[x]++,cnt++,ToT=ToT*cnt%mod*inv[Gs[x]]%mod):(ToT=ToT*inv[cnt]%mod*Gs[x]%mod,Gs[x]--,cnt--);} int main(){ freopen("dierti.in","r",stdin);freopen("dierti.out","w",stdout); re int i,j,h;scanf("%s",s+1);n=strlen(s+1);for(inv[0]=i=1;i<=n;i++) inv[i]=mpow(i); H.Make();A.MakeMod(1000000009);B.MakeMod(1000000007);/*C.MakeMod(998244353);*/for(i=1;i<=n;i++){ clear();if(n%i==0){ for(j=1;j<=n;j+=i) insert(H.Getline(j,j+i-1),1);Ans+=ToT;continue; }A.clear();B.clear();//C.clear(); for(j=n%i+1;j<=n;j+=i) pus=H.Getline(j,j+i-1),A.insert(pus,1),B.insert(pus,1),/*C.insert(pus,1),*/insert(pus,1); (A.Find()||B.Find()/*||C.Find()*/)&&(A.Get(),B.Get()/*,C.Get()*/,Ans+=ToT); for(j=i+1;j<=n;j+=i){ pus=H.Getline(j-i,j-1);A.insert(pus,1);B.insert(pus,1);/*C.insert(pus,1);*/insert(pus,1); pus=H.Getline(j+n%i-i,j+n%i-1);A.insert(pus,-1);B.insert(pus,-1);/*C.insert(pus,-1);*/insert(pus,-1); (A.Find()||B.Find()/*||C.Find()*/)&&(A.Get(),B.Get(),/*C.Get(),*/Ans+=ToT); } // if(clock()>1950){printf("890964726\n");return 0;} }printf("%lld\n",Ans%mod); }