后缀数组小结?
Posted Mafia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后缀数组小结?相关的知识,希望对你有一定的参考价值。
做了一圈(就那么几道还叫一圈)$SA$的题,小结一下,方便自己看
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define mem(x) memset((x),0,sizeof((x))) 6 struct SA{ 7 char s[60005]; 8 int n,m; 9 int t1[60005],t2[60005],t3[60005],buc[60005]; 10 int sa[60005],Rank[60005],height[60005],mn[60005][20]; 11 SA(){} 12 inline void clear(){ 13 m=130; 14 mem(t1),mem(t2),mem(t3),mem(buc),mem(sa),mem(Rank),mem(height),mem(mn); 15 } 16 inline void init(){ 17 scanf("%s",s+1); 18 n=strlen(s+1); 19 } 20 inline void Suffix(){ 21 int i,j,k(0),p(0),*x(t1),*y(t2),*t; 22 for(i=0;i<=m;++i)buc[i]=0; 23 for(i=1;i<=n;++i)++buc[x[i]=s[i]]; 24 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 25 for(i=n;i>=1;--i)sa[buc[x[i]]--]=i; 26 for(j=1;p<n;j<<=1,m=p){ 27 for(p=0,i=n-j+1;i<=n;++i)y[++p]=i; 28 for(i=1;i<=n;++i) 29 if(sa[i]>j) 30 y[++p]=sa[i]-j; 31 for(i=0;i<=m;++i)buc[i]=0; 32 for(i=1;i<=n;++i)t3[i]=x[y[i]]; 33 for(i=1;i<=n;++i)++buc[t3[i]]; 34 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 35 for(i=n;i>=1;--i)sa[buc[t3[i]]--]=y[i]; 36 for(t=x,x=y,y=t,x[sa[1]]=1,p=1,i=2;i<=n;++i) 37 x[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+j]==y[sa[i-1]+j]))?p:++p; 38 } 39 for(i=1;i<=n;++i)Rank[sa[i]]=i; 40 for(i=1;i<=n;height[Rank[i++]]=k) 41 for(k?--k:0,j=sa[Rank[i]-1];s[i+k]==s[j+k];++k); 42 } 43 inline void ST(){ 44 for(int i=1;i<=n;++i)mn[i][0]=height[i]; 45 for(int i=1;(1<<i)<=n;++i) 46 for(int j=1;j+(1<<i)-1<=n;++j) 47 mn[j][i]=min(mn[j][i-1],mn[j+(1<<i-1)][i-1]); 48 } 49 inline int lcp(int x,int y){ 50 if(y>n)return 0; 51 x=Rank[x],y=Rank[y]; 52 if(x>y)swap(x,y); 53 ++x; 54 int k(0),len(y-x+1); 55 while((1<<k)<=len)++k; 56 --k; 57 return min(mn[x][k],mn[y-(1<<k)+1][k]); 58 } 59 inline void work(){ 60 Suffix(); 61 ST(); 62 } 63 }a,b; 64 inline void inv(){ 65 b.n=a.n; 66 for(int i=1;i<=a.n;++i) 67 b.s[i]=a.s[a.n-i+1]; 68 } 69 typedef long long L; 70 L ans; 71 L cnt1[30005],cnt2[30005]; 72 inline void doit(){ 73 ans=0; 74 mem(cnt1),mem(cnt2); 75 int edge(a.n>>1); 76 for(int l=1;l<=edge;++l) 77 for(int i=l,j=l<<1;j<=a.n;i+=l,j+=l){ 78 int x(min(a.lcp(i,j),l)); 79 int y(min(b.lcp(a.n-(i-1)+1,a.n-(j-1)+1),l-1)); 80 int tmp(x+y-l+1); 81 if(x+y>=l){ 82 ++cnt1[i-y];--cnt1[i-y+tmp]; 83 ++cnt2[j+x-tmp];--cnt2[j+x]; 84 } 85 } 86 for(int i=1;i<=a.n;++i) 87 cnt1[i]+=cnt1[i-1],cnt2[i]+=cnt2[i-1]; 88 for(int i=1;i<=a.n;++i) 89 ans+=cnt1[i+1]*cnt2[i]; 90 printf("%lld\\n",ans); 91 } 92 int main(){ 93 int T; 94 scanf("%d",&T); 95 while(T--){ 96 a.clear(),b.clear(); 97 a.init(); 98 a.work(); 99 inv(); 100 b.work(); 101 doit(); 102 } 103 }
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 inline int read(){ 6 int sum(0); 7 char ch(getchar()); 8 for(;ch<\'0\'||ch>\'9\';ch=getchar()); 9 for(;ch>=\'0\'&&ch<=\'9\';sum=sum*10+(ch^48),ch=getchar()); 10 return sum; 11 } 12 int n,m,q; 13 char s[100005]; 14 int t1[100005],t2[100005],t3[100005],buc[100005]; 15 int sa[100005],rank[100005],height[100005],mn[100005][20]; 16 inline void Suffix(){ 17 int i,j,k(0),p(0),*x(t1),*y(t2),*t; 18 for(i=0;i<=m;++i)buc[i]=0; 19 for(i=1;i<=n;++i)++buc[x[i]=s[i]]; 20 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 21 for(i=n;i>=1;--i)sa[buc[x[i]]--]=i; 22 for(j=1;p<n;j<<=1,m=p){ 23 for(p=0,i=n-j+1;i<=n;++i)y[++p]=i; 24 for(i=1;i<=n;++i) 25 if(sa[i]>j) 26 y[++p]=sa[i]-j; 27 for(i=0;i<=m;++i)buc[i]=0; 28 for(i=1;i<=n;++i)t3[i]=x[y[i]]; 29 for(i=1;i<=n;++i)++buc[t3[i]]; 30 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 31 for(i=n;i>=1;--i)sa[buc[t3[i]]--]=y[i]; 32 for(t=x,x=y,y=t,x[sa[1]]=1,p=1,i=2;i<=n;++i) 33 x[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+j]==y[sa[i-1]+j]))?p:++p; 34 } 35 for(i=1;i<=n;++i)rank[sa[i]]=i; 36 for(i=1;i<=n;height[rank[i++]]=k) 37 for(k?--k:0,j=sa[rank[i]-1];s[i+k]==s[j+k];++k); 38 } 39 inline void ST(){ 40 for(int i=1;i<=n;++i) 41 mn[i][0]=height[i]; 42 for(int i=1;(1<<i)<=n;++i) 43 for(int j=1;j+(1<<i)-1<=n;++j) 44 mn[j][i]=min(mn[j][i-1],mn[j+(1<<i-1)][i-1]); 45 } 46 int cnt; 47 int rt[100005],lch[2000005],rch[2000005],sum[2000005]; 48 inline void update(int &x,int las,int pos,int l,int r){ 49 x=++cnt; 50 // cout<<x<<\' \'<<las<<\' \'<<pos<<\' \'<<l<<\' \'<<r<<endl; 51 lch[x]=lch[las]; 52 rch[x]=rch[las]; 53 sum[x]=sum[las]+1; 54 if(l==r) 55 return; 56 int mid((l+r)>>1); 57 if(pos<=mid) 58 update(lch[x],lch[las],pos,l,mid); 59 else 60 update(rch[x],rch[las],pos,mid+1,r); 61 } 62 inline int query(int x,int y,int ll,int rr,int l,int r){ 63 if(ll<=l&&r<=rr) 64 return sum[y]-sum[x]; 65 int mid((l+r)>>1); 66 if(rr<=mid) 67 return query(lch[x],lch[y],ll,rr,l,mid); 68 if(mid<ll) 69 return query(rch[x],rch[y],ll,rr,mid+1,r); 70 return query(lch[x],lch[y],ll,mid,l,mid)+query(rch[x],rch[y],mid+1,rr,mid+1,r); 71 } 72 int main(){ 73 n=read(),q=read(),m=130; 74 scanf("%s",s+1); 75 Suffix(); 76 ST(); 77 for(int i=1;i<=n;++i) 78 update(rt[i],rt[i-1],rank[i],1,n); 79 while(q--){ 80 int a(read()),b(read()),c(read()),d(read()); 81 int l(1),r(min(b-a+1,d-c+1)),mid,ans=0; 82 int tp(rank[c]); 83 while(l<=r){ 84 mid=(l+r)>>1; 85 int tp1(tp),tp2(tp); 86 for(int i=16;i>=0;--i) 87 if(tp1>=(1<<i)&&mn[tp1-(1<<i)+1][i]>=mid) 88 tp1-=(1<<i); 89 for(int i=16;i>=0;--i) 90 if(tp2+(1<<i)<=n&&mn[tp2+1][i]>=mid) 91 tp2+=(1<<i);//cout<<l<<\' \'<<r<<\' \'<<mid<<\' \'<<tp1<<" "<<tp2<<endl; 92 if(query(rt[a-1],rt[b-mid+1],tp1,tp2,1,n)>0) 93 ans=mid,l=mid+1; 94 else 95 r=mid-1; 96 } 97 printf("%d\\n",ans); 98 } 99 }
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 char s[100005]; 7 int n,m; 8 int t1[100005],t2[100005],t3[100005],buc[100005]; 9 int sa[100005],rank[100005],height[100005]; 10 inline void Suffix(){ 11 int i,j,k(0),p(0),*x(t1),*y(t2),*t; 12 for(i=0;i<=m;++i)buc[i]=0; 13 for(i=1;i<=n;++i)++buc[x[i]=s[i]]; 14 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 15 for(i=n;i>=1;--i)sa[buc[x[i]]--]=i; 16 for(j=1;p<n;j<<=1,m=p){ 17 for(p=0,i=n-j+1;i<=n;++i)y[++p]=i; 18 for(i=1;i<=n;++i) 19 if(sa[i]>j) 20 y[++p]=sa[i]-j; 21 for(i=0;i<=m;++i)buc[i]=0; 22 for(i=1;i<=n;++i)t3[i]=x[y[i]]; 23 for(i=1;i<=n;++i)++buc[t3[i]]; 24 for(i=1;i<=m;++i)buc[i]+=buc[i-1]; 25 for(i=n;i>=1;--i)sa[buc[t3[i]]--]=y[i]; 26 for(t=x,x=y,y=t,x[sa[1]]=1,p=1,i=2;i<=n;++i) 27 x[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+j]==y[sa[i-1]+j]))?p:++p; 28 } 29 for(i=1;i<=n;++i)rank[sa[i]]=i; 30 for(i=1;i<=n;height[rank[i++]]=k) 31 for(k?--k:0,j=sa[rank[i]-1];s[i+k]==s[j+k];++k); 32 } 33 int k; 34 typedef long long L; 35 L tot; 36 int ansl,ansr,ll,rr; 37 /*inline void get_kth(L x){ 38 for(int i=1;i<=n;++i){ 39 if(x>(L)(n-sa[i]-height[i]+1)) 40 x-=(L)(n-sa[i]-height[i]+1); 41 else{ 42 ll=sa[i],rr=sa[i]+height[i]+k-1; 43 return; 44 } 45 } 46 }*/ 47 inline bool cmp(int l,int r){ 48 for(int i=l,j=ll;i<=r&&j<=rr;++i,++j){ 49 if(s[i]<s[j]) 50 return true; 51 if(s[i]>s[j]) 52 return false; 53 } 54 // cout<<l<<\' \'<<r<<\' \'<<ll<<\' \'<<rr<<endl; 55 if(rr-ll<r-l) 56 return false; 57 return true; 58 } 59 inline bool check(){ 60 int i,j,cnt(0); 61 for(i=n;i>=1;i=j,++cnt){ 62 for(j=i;j>0;--j) 63 if(!cmp(j,i)) 64 break; 65 if(i==j) 66 return false; 67 } 68 return cnt<=k; 69 } 70 L sum[100005]; 71 int main(){ 72 scanf("%d%s",&k,s+1); 73 n=strlen(s+1); 74 m=130; 75 Suffix(); 76 tot=n; 77 for(int i=1;i<=n;++i){ 78 sum[i]=n-sa[i]+1-height[i]; 79 sum[i]+=sum[i-1]; 80 tot+=n-sa[i]-height[i]; 81 } 82 L l(0),r(tot); 83 while(l<=r){ 84 L mid((l+r)>>1); 85 // cout<<l<<\' \'<<r<<" "<<mid<<endl; 86 // get_kth(mid); 87 L tmp(lower_bound(sum+1,sum+n+1,mid)-sum); 88 ll=sa[tmp],rr=mid-sum[tmp-1]+sa[tmp]+height[tmp]-1; 89 // cout<<ll<<\' \'<<rr<<\' \'<<mid<<endl; 90 if(check()){ 91 ansl=ll,ansr=rr; 92 r=mid-1; 93 } 94 else 95 l=mid+1; 96 } 97 // cout<<ansl<<\' \'<<ansr<<endl; 98 for(int i=ansl;i<=ansr;++i) 99 putchar(s[i]); 100 }