1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<map> #include<set> #include<queue> #include<deque> #include<stack> #include<bitset> #include<vector> #include<algorithm> #include<iostream> using namespace std; #ifdef DEBUG const int LOCAL=1; #else const int LOCAL=0; #endif
namespace mine { typedef long long ll; const int INF=0x3f3f3f3f; int () { int ans=0,f=1;char c=getchar(); while(c<'0' or c>'9') {if(c=='-') f=-1;;c=getchar();} while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar(); return ans*f; }
const int MAX_N=3100; char str[MAX_N];int len; struct Sa { int sa[MAX_N],tmp[MAX_N]; int rk[MAX_N*2],rk2[MAX_N*2]; int ct[MAX_N]; bool diff(int a,int b,int ln) {return rk2[a]!=rk2[b] or rk2[a+ln]!=rk2[b+ln];} void build() { memset(ct,0,sizeof ct); for(int i=1;i<=len;i++) ct[rk[i]=str[i]]++; for(int i=1;i<MAX_N;i++) ct[i]+=ct[i-1]; for(int i=len;i>=1;i--) sa[ct[rk[i]]--]=i;
int ln=1; while(ln<len) { int cnt=0;for(int i=len-ln+1;i<=len;i++) tmp[++cnt]=i; for(int i=1;i<=len;i++) if(sa[i]-ln>=1) tmp[++cnt]=sa[i]-ln;
memset(ct,0,sizeof ct); for(int i=1;i<=len;i++) ct[rk[tmp[i]]]++; for(int i=1;i<MAX_N;i++) ct[i]+=ct[i-1]; for(int i=len;i>=1;i--) sa[ct[rk[tmp[i]]]--]=tmp[i];
cnt=0;memcpy(rk2,rk,sizeof rk);sa[0]=0; for(int i=1;i<=len;i++) { if(diff(sa[i-1],sa[i],ln)) cnt++; rk[sa[i]]=cnt; }
ln*=2; } } int hei[MAX_N]; void geth() { int lst=0; for(int i=1;i<=len;i++) { if(rk[i]==1) {hei[1]=0;continue;} if(lst) lst--; while(max(sa[rk[i]-1],i)+lst<=len and str[sa[rk[i]-1]+lst]==str[i+lst]) lst++; hei[rk[i]]=lst; } } }sa; int bom[MAX_N]; void main() { scanf("%d%s",&len,str+1); sa.build(); sa.geth();
for(int i=1;i<=len;i++) { int pos=sa.sa[i]; for(int t=bom[i]+1;pos+t-1<=len;t++) { int nxt=i; while(nxt+1<=len and sa.hei[nxt+1]>=t) bom[++nxt]=t; if(nxt-i+1>1) printf("%dn",nxt-i+1); } } } }; int main() { srand(time(0)); mine::main(); }
|
近期评论