1 条题解
-
0
C++ :
#include<string.h> #include<stdio.h> #include<algorithm> #define MAXN 2100000 using namespace std; class DC3{ public: char* ch; int *rank0,*SA; int n; int cnt0,cnt1,cnt2; static int sum[MAXN]; static int tmpSA[MAXN]; static int tmpRank[MAXN]; DC3(){} DC3(int* _rank0,int* _SA,int _n,char* s=NULL){ rank0=_rank0; SA=_SA; n=_n; rank0[n]=rank0[n+1]=-1; if(s==NULL) return; for(int i=0;i<n;i++) rank0[i]=s[i]; ch=s; } void getH(int* h){ for(int i=0;i<n;i++){ if(rank0[i]==0){ h[i]=0; } else { h[i]=(i?max(0,h[i-1]-1):0); for(;h[i]<n&&ch[i+h[i]]==ch[SA[rank0[i]-1]+h[i]];h[i]++); } } } void radixSort(int* rank0,int* SA,int n){ int maxKey=0; for(int i=0;i<n;i++){ sum[rank0[SA[i]]+2]++; maxKey=max(maxKey,rank0[SA[i]]+2); } for(int i=1;i<=maxKey+1;i++) sum[i]+=sum[i-1]; for(int i=0;i<n;i++){ tmpSA[sum[rank0[SA[i]]+1]++] = SA[i]; } memcpy(SA,tmpSA,sizeof(int)*n); memset(sum,0,sizeof(int)*(maxKey+2)); } int convert(int x){ if(x<cnt1)return x*3+1; return (x-cnt1-1)*3+2; } int co_convert(int x){ if(x%3==1)return x/3; return x/3+cnt1+1; } bool compare(int i,int j,int* nextRank){ if(rank0[i]!=rank0[j])return rank0[i]<rank0[j]; if(i%3+j%3==3)return nextRank[co_convert(i)]<nextRank[co_convert(j)]; return compare(i+1,j+1,nextRank); } bool operator ()(int a,int b){ if(a==b)return false; while(rank0[a]==rank0[b])++a,++b; return rank0[a]<rank0[b]; } void solve(){ for(int i=0;i<n;i++) SA[i]=i; if(n<=100){ sort(SA,SA+n,*this); for(int i=0;i<n;i++) rank0[SA[i]]=i; return; } radixSort(rank0+2,SA,n); radixSort(rank0+1,SA,n); radixSort(rank0,SA,n); tmpRank[SA[0]]=0; for(int i=1;i<n;i++) tmpRank[SA[i]]=tmpRank[SA[i-1]]+ (rank0[SA[i]]!=rank0[SA[i-1]]|| rank0[SA[i]+1]!=rank0[SA[i-1]+1]|| rank0[SA[i]+2]!=rank0[SA[i-1]+2]); memcpy(rank0,tmpRank,sizeof(int)*n); if(rank0[SA[n-1]]==n-1)return; int* nextRank=rank0+n+2; int nextN=0; cnt1=cnt2=0; for(int i=1;i<n;i+=3){ nextRank[nextN++]=rank0[i]+1; cnt1++; } nextRank[nextN++]=0; for(int i=2;i<n;i+=3){ nextRank[nextN++]=rank0[i]+1; cnt2++; } cnt0=n-cnt1-cnt2; int* nextSA=SA+n; DC3 next(nextRank,nextSA,nextN); next.solve(); for(int i=0;i<nextN;i++){ if(nextRank[i]==0)continue; tmpRank[convert(i)]=nextRank[i]; } for(int i=0;i<n;i+=3) SA[i/3]=i; radixSort(tmpRank+1,SA,cnt0); radixSort(rank0,SA,cnt0); memcpy(tmpSA,SA,sizeof(int)*cnt0); for(int i=1,j=0,cnt=0;i<=nextN;i++){ while(j<cnt0&&(i==nextN||compare(tmpSA[j],convert(nextSA[i]),nextRank))){ SA[cnt++]=tmpSA[j++]; } SA[cnt++]=convert(nextSA[i]); } for(int i=0;i<n;i++) rank0[SA[i]]=i; } }; int DC3::sum[MAXN]={}; int DC3::tmpSA[MAXN]; int DC3::tmpRank[MAXN]; int rank0[3*MAXN],SA[3*MAXN],h[MAXN]; char ch[MAXN]; int st[MAXN]; int len[MAXN]; int half[MAXN]; int rmq[MAXN][20]; void build_rmq(int L){ half[0]=0; for(int i=1;i<=L;i++){ half[i]=half[i-1]; if((2<<half[i])==i)half[i]++; } for(int i=0;i<L;i++){ rmq[i][0]=h[SA[i]]; } for(int r=1;r<20;r++){ for(int i=0;i+(1<<r)<=L;i++) rmq[i][r]=min(rmq[i][r-1],rmq[i+(1<<(r-1))][r-1]); } } int query(int fr,int to){ if(fr==to)return 987654321; int L=half[to-fr]; fr++; return min(rmq[fr][L],rmq[to-(1<<L)+1][L]); } int main(){ int n,L=0; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s",ch+L); st[i]=L; len[i]=strlen(ch+L); L+=len[i]+1; ch[L-1]='a'-1; } DC3 dc3=DC3(rank0,SA,L,ch); dc3.solve(); dc3.getH(h); build_rmq(L); for(int i=0;i<n;i++){ int x=rank0[st[i]]; int fr=0,to=L-1; int tmp=x; while(tmp-fr>1){ int mid=(tmp+fr)/2; if(query(mid,x)>=len[i])tmp=mid; else fr=mid; } if(query(x,to)>=len[i])to++; else { tmp=x; while(to-tmp>1){ int mid=(tmp+to)/2; if(query(x,mid)>=len[i])tmp=mid; else to=mid; } } printf("%d\n",to-fr-1); } }
- 1
信息
- ID
- 1028
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者