CF1056E Check Transcription(SA)
阿新 • • 發佈:2020-08-24
對於本題,要發現的一點是,因為0,1各代表一個字串,因此我們可以暴力列舉0代表的是什麼,1代表的是什麼,一個是字首,另一個受前一個控制。
對於判斷兩個子串是否相等,可以使用雜湊,這裡我採用的是字尾陣列求lcp,只要比較一下是否大於等於我們列舉的長度即可。
最後我們要判斷一下0和1代表的東西不能夠相等
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pll> plll; const int N=1e6+10View Code; const int mod=1e9+7; char s[N],t[N]; int sa[N],rk[N],od[N],cnt[N],id[N],px[N]; ll h[N]; ll f[N][26]; ll lg[N]; bool cmp(int x, int y, int w) { return od[x]==od[y]&&od[x + w]==od[y + w]; } void da(int n,int m){ int i; memset(cnt,0,sizeof cnt); for(i=1;i<=n;i++) cnt[rk[i]=t[i]]++;for(i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for(i=n;i>=1;i--) sa[cnt[rk[i]]--]=i; int p; for(int w=1;w<n;w<<=1,m=p){ p=0; for(i=n;i>n-w;i--) id[++p]=i; for(i=1;i<=n;i++) if(sa[i]>w) id[++p]=sa[i]-w; memset(cnt,0,sizeof cnt); for(i=1;i<=n;i++) cnt[px[i]=rk[id[i]]]++; for(i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for(i=n;i>=1;i--) sa[cnt[px[i]]--]=id[i]; for(i=0;i<=n;i++) od[i]=rk[i]; for(p=0,i=1;i<=n;i++){ rk[sa[i]]=cmp(sa[i-1],sa[i],w)?p:++p; } } } void st(int n){ int i,j; for(i=1;i<=n;i++) f[i][0]=h[i]; lg[1]=0; for(i=2;i<=n;i++) lg[i]=lg[i>>1]+1; for(j=1;j<=lg[n];j++){ for(i=1;i+(1<<j)-1<=n;i++){ f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]); } } } int query(int l,int r){ if(l>r) swap(l,r); l++; int len=lg[r-l+1]; return min(f[l][len],f[r-(1<<len)+1][len]); } void get_height(int n){ int i; for(i=1;i<=n;i++){ if(rk[i]==1) continue; int a=max(h[rk[i-1]]-1,1ll*0); while(i+a<=n&&t[i+a]==t[sa[rk[i]-1]+a]) a++; h[rk[i]]=a; } st(n); } int main(){ //ios::sync_with_stdio(false); scanf("%s%s",s+1,t+1); int lent=strlen(t+1); int lens=strlen(s+1); da(lent,128); get_height(lent); int cnt0=0,cnt1=0; for(int i=1;i<=lens;i++){ if(s[i]=='0') cnt0++; else cnt1++; } ll ans=0; for(ll i=1;i*cnt0<=lent;++i){ if((lent-i*cnt0)%(lens-cnt0))continue; ll start0=0,start1=0,pos=1,flag=1; ll k=(lent-i*cnt0)/(lens-cnt0); for(ll j=1;j<=lens;++j){ if(s[j]=='0'){ if(!start0)start0=pos; else if(query(rk[start0],rk[pos])<i)flag=0; pos+=i; } else{ if(!start1)start1=pos; else if(query(rk[start1],rk[pos])<k)flag=0; if(!k)flag=0; pos+=k; } } if(flag&&(i!=k||query(rk[start0],rk[start1])<i))++ans; } cout<<ans<<endl; return 0; }