标签:
今天重新看了一下后缀自动机的,感受颇深。网上对后缀自动机的介绍以及很详细了,所以只记录一下自己的心得和体会。
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=2*10000; int N; char s[maxN+1000]; struct SAM { struct node { int ch[26],fail,maxlen,minlen,size; /* maxlen:能接受的最长字符串长度 minlen:能接受的最短字符串长度,为fail的maxlen+1 maxlen-minlen+1:能接受的不同字符串种数 size:表示这个状态出现了几次,状态能够表示的所有字符串均出现过size次 fail-tree恰好是字符串逆序的后缀树 ch构成一个有向无环图 */ inline void clear(){mmst(ch,0);fail=maxlen=minlen=size=0;} }; node sn[maxN*2+1000];//空间要乘2 int idx,last; inline void clear(){idx=last=1;sn[idx].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int c) { int end=newnode(); int p=last; last=end;//注意这句话 sn[end].maxlen=sn[p].maxlen+1; for(;p && !sn[p].ch[c];p=sn[p].fail)sn[p].ch[c]=end;//这里生成了新的子串 if(!p)sn[end].fail=1;//注意root是1 else { int q=sn[p].ch[c]; if(sn[p].maxlen+1==sn[q].maxlen)sn[end].fail=q; else { int nq=newnode(); sn[nq]=sn[q]; sn[nq].maxlen=sn[p].maxlen+1; sn[q].fail=sn[end].fail=nq; for(;p && sn[p].ch[c]==q;p=sn[p].fail)sn[p].ch[c]=nq; } } sn[end].minlen=sn[sn[end].fail].maxlen+1; /* for(int p=end;p!=1;p=sn[p].fail)sn[p].size++; 这样写为暴力修改size,遇到连续个相同字符的数据就会超时 可以用LCT优化,具体见bzoj2555 */ } int cnt[maxN+100],b[2*maxN+100]; inline void insert(char *s,int N) { int i,p; clear(); re(i,1,N)add(s[i]-‘a‘); re(i,1,N)cnt[i]=0; re(i,1,idx)cnt[sn[i].maxlen]++; re(i,1,N)cnt[i]+=cnt[i-1]; re(i,1,idx)b[cnt[sn[i].maxlen]--]=i; p=1;re(i,1,N){p=sn[p].ch[s[i]-‘a‘];sn[p].size++;} red(i,N,1){p=b[i];if(sn[p].fail!=1)sn[sn[p].fail].size+=sn[p].size;} } };
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=2*10000; int N; char s[maxN+1000]; struct SAM { struct node { int ch[26],fail,len; inline void clear(){mmst(ch,0);fail=len=0;} }; node sn[maxN*2+1000];//空间要乘2 int idx,last; inline void clear(){idx=last=1;sn[idx].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int c) { int end=newnode(); int p=last; last=end;//注意这句话 sn[end].len=sn[p].len+1; for(;p && !sn[p].ch[c];p=sn[p].fail)sn[p].ch[c]=end; if(!p){sn[end].fail=1;return;}//注意root是1 int q=sn[p].ch[c]; if(sn[p].len+1==sn[q].len){sn[end].fail=q;return;} int nq=newnode(); sn[nq]=sn[q]; sn[nq].len=sn[p].len+1; sn[q].fail=sn[end].fail=nq; for(;p && sn[p].ch[c]==q;p=sn[p].fail)sn[p].ch[c]=nq; } inline void insert(char *s,int N) { int i; clear(); re(i,1,N)add(s[i]-‘a‘); } }; SAM sam; int main() { freopen("poj1509.in","r",stdin); freopen("poj1509.out","w",stdout); int i,j; for(int Case=gint();Case;Case--) { scanf("%s\n",s+1); N=strlen(s+1); re(i,1,N)s[N+i]=s[i]; sam.insert(s,2*N); int p=1; re(i,1,N)re(j,0,26-1) if(sam.sn[p].ch[j]){p=sam.sn[p].ch[j];break;} printf("%d\n",sam.sn[p].len-N+1); } return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=250000; struct SAM { struct node { int ch[26],fail,maxlen; inline void clear(){mmst(ch,0);fail=maxlen=0;} }; node sn[2*maxN+1000]; int idx,last; inline void clear(){sn[idx=last=1].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int c) { int end=newnode(); int p=last; last=end; sn[end].maxlen=sn[p].maxlen+1; for(;p && !sn[p].ch[c];p=sn[p].fail)sn[p].ch[c]=end; if(!p){sn[end].fail=1;return;} int q=sn[p].ch[c]; if(sn[p].maxlen+1==sn[q].maxlen){sn[end].fail=q;return;} int nq=newnode(); sn[nq]=sn[q]; sn[nq].maxlen=sn[p].maxlen+1; sn[q].fail=sn[end].fail=nq; for(;p && sn[p].ch[c]==q;p=sn[p].fail)sn[p].ch[c]=nq; } inline void insert(char *s,int N) { int i; clear(); re(i,1,N)add(s[i]-‘a‘); } }; int lena,lenb; char a[maxN+100],b[maxN+100]; SAM sam; int ans; int main() { freopen("spoj1811.in","r",stdin); freopen("spoj1811.out","w",stdout); int i; scanf("%s\n",a+1);lena=strlen(a+1); scanf("%s\n",b+1);lenb=strlen(b+1); sam.insert(a,lena); ans=0; int clen=0,p=1; re(i,1,lenb) { int c=b[i]-‘a‘; if(sam.sn[p].ch[c]) { p=sam.sn[p].ch[c]; clen++; } else { while(p!=1 && !sam.sn[p].ch[c])p=sam.sn[p].fail; if(!sam.sn[p].ch[c]) clen=0; else { clen=sam.sn[p].maxlen+1; p=sam.sn[p].ch[c]; } } upmax(ans,clen); } cout<<ans<<endl; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxT=10; const int maxN=100000; struct SAM { struct Tnode { int ch[26],fail,l,nl,ml; inline void clear(){mmst(ch,0);fail=l=nl=ml=0;} }sn[2*maxN+1000]; int idx,last; inline void clear(){sn[idx=last=1].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; sn[end].l=sn[p].l+1; for(;p && !sn[p].ch[z];p=sn[p].fail)sn[p].ch[z]=end; if(!p)sn[end].fail=1; else { int q=sn[p].ch[z]; if(sn[p].l+1==sn[q].l) sn[end].fail=q; else { int nq=newnode(); sn[nq]=sn[q]; sn[q].fail=sn[end].fail=nq; sn[nq].l=sn[p].l+1; for(;p && sn[p].ch[z]==q;p=sn[p].fail)sn[p].ch[z]=nq; } } } int cnt[maxN+100],b[2*maxN+100]; inline void insert(char *s) { int i,N=strlen(s+1); clear(); re(i,1,N)add(s[i]-‘a‘); re(i,1,N)cnt[i]=0; re(i,1,idx)cnt[sn[i].l]++; re(i,1,N)cnt[i]+=cnt[i-1]; re(i,1,idx)b[cnt[sn[i].l]--]=i; } }; int T; char s[maxT+3][maxN+1000]; SAM sam; int main() { freopen("spoj1812.in","r",stdin); freopen("spoj1812.out","w",stdout); int i,j; while(scanf("%s\n",s[++T]+1)!=EOF);T--; sam.insert(s[1]); re(i,2,sam.idx)sam.sn[i].ml=sam.sn[i].l; re(i,2,T) { int N=strlen(s[i]+1),p=1,len=0; re(j,1,N) { int z=s[i][j]-‘a‘; while(p!=1 && !sam.sn[p].ch[z]){p=sam.sn[p].fail;len=sam.sn[p].l;} if(sam.sn[p].ch[z]){len++;p=sam.sn[p].ch[z];} upmax(sam.sn[p].nl,len); } red(j,sam.idx,2) { int p=sam.b[j]; upmin(sam.sn[p].ml,sam.sn[p].nl); if(sam.sn[p].fail!=1) upmax(sam.sn[sam.sn[p].fail].nl,sam.sn[p].nl); sam.sn[p].nl=0; } } int ans=0; re(i,1,sam.idx)upmax(ans,sam.sn[i].ml); cout<<ans<<endl; return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=50000+200000; const int maxM=200000; const int maxK=50000; int N,K,M; LL ans; struct SAM { struct Tnode { int ch[26],fail,l,right; inline void clear(){mmst(ch,0);fail=l=right=0;} }node[2*maxN+1000]; int idx,last; inline void clear(){node[idx=last=1].clear();} inline int newnode(){node[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; node[end].l=node[p].l+1; for(;p && !node[p].ch[z];p=node[p].fail)node[p].ch[z]=end; if(!p)node[end].fail=1; else { int q=node[p].ch[z]; if(node[p].l+1==node[q].l)node[end].fail=q; else { int nq=newnode(); node[nq]=node[q]; node[q].fail=node[end].fail=nq; node[nq].l=node[p].l+1; for(;p && node[p].ch[z]==q;p=node[p].fail)node[p].ch[z]=nq; } } for(p=end;p!=1;p=node[p].fail) { node[p].right++; if(node[p].right>K)break; if(node[p].right==K) { int ge=node[p].l-node[node[p].fail].l; ans+=LL(ge); } } } }; SAM sam; int main() { freopen("hdu4641.in","r",stdin); freopen("hdu4641.out","w",stdout); int i; while(scanf("%d%d%d\n",&N,&M,&K)!=EOF) { sam.clear(); ans=0; re(i,1,N) { char z=getchar(); sam.add(z-‘a‘); } while(M--) { int flag=gint(); if(flag==2) printf("%I64d\n",ans); else { char z=getchar(); sam.add(z-‘a‘); } } } return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=90000; struct SAM { struct Tnode { int ch[26],fail,l; LL cnt; inline void clear(){mmst(ch,0);fail=l=0;cnt=0;} }sn[2*maxN+100]; int idx,last; inline void clear(){sn[idx=last=1].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; sn[end].l=sn[p].l+1; for(;p && !sn[p].ch[z];p=sn[p].fail)sn[p].ch[z]=end; if(!p)sn[end].fail=1; else { int q=sn[p].ch[z]; if(sn[p].l+1==sn[q].l)sn[end].fail=q; else { int nq=newnode(); sn[nq]=sn[q]; sn[nq].l=sn[p].l+1; sn[q].fail=sn[end].fail=nq; for(;p && sn[p].ch[z]==q;p=sn[p].fail)sn[p].ch[z]=nq; } } } inline void insert(char *s) { int i,N=strlen(s+1); clear(); re(i,1,N)add(s[i]-‘a‘); } }; SAM sam; char s[maxN+100]; int du[2*maxN+100]; int head,tail,que[2*maxN+100]; int ge,out[maxN+100]; int main() { freopen("spoj7258.in","r",stdin); freopen("spoj7258.out","w",stdout); int i,j; scanf("%s\n",s+1); sam.insert(s); re(i,1,sam.idx)re(j,0,26-1)if(sam.sn[i].ch[j]) du[sam.sn[i].ch[j]]++; head=0;tail=-1; re(i,1,sam.idx)if(du[i]==0)que[++tail]=i; while(head<=tail) { int u=que[head++]; re(j,0,26-1)if(sam.sn[u].ch[j]) { int v=sam.sn[u].ch[j]; du[v]--; if(du[v]==0)que[++tail]=v; } } red(i,tail,0) { int u=que[i]; sam.sn[u].cnt=1; re(j,0,26-1)if(sam.sn[u].ch[j]) { int v=sam.sn[u].ch[j]; sam.sn[u].cnt+=sam.sn[v].cnt; } } for(int Q=gint();Q;Q--) { LL K=gll(); int u=1; ge=0; while(K!=0) { re(i,0,26-1) { int v=sam.sn[u].ch[i]; if(sam.sn[v].cnt<K) K-=sam.sn[v].cnt; else { out[++ge]=i; u=v; K--; break; } } } re(i,1,ge)printf("%c",out[i]+‘a‘);printf("\n"); } return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=2000; const int maxQ=10000; int N; char s[maxN+100]; int Q; struct Tdata { int l,r,id; LL ans; }data[maxQ+100]; inline bool cmp(Tdata a,Tdata b){return (a.l==b.l)?a.r<b.r:a.l<b.l;} inline bool cmpid(Tdata a,Tdata b){return a.id<b.id;} struct SAM { struct Tnode { int ch[26],fail,l; inline void clear(){mmst(ch,0);fail=l=0;} }sn[2*maxN+100]; int idx,last; LL cnt; inline void clear(){cnt=0;sn[idx=last=1].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; sn[end].l=sn[p].l+1; for(;p && !sn[p].ch[z];p=sn[p].fail) { sn[p].ch[z]=end; if(p!=1) cnt+=LL(sn[p].l-sn[sn[p].fail].l); else cnt++; } if(!p) sn[end].fail=1; else { int q=sn[p].ch[z]; if(sn[p].l+1==sn[q].l) sn[end].fail=q; else { int nq=newnode(); sn[nq]=sn[q]; sn[nq].l=sn[p].l+1; sn[q].fail=sn[end].fail=nq; for(;p && sn[p].ch[z]==q;p=sn[p].fail)sn[p].ch[z]=nq; } } } }; SAM sam; int main() { freopen("hdu4622.in","r",stdin); freopen("hdu4622.out","w",stdout); int i,j; for(int Case=gint();Case;Case--) { scanf("%s\n",s+1); Q=gint(); re(i,1,Q)data[i].l=gint(),data[i].r=gint(),data[i].id=i; sort(data+1,data+Q+1,cmp); int r; re(i,1,Q) { if(data[i].l!=data[i-1].l){sam.clear();r=data[i].l-1;} re(j,r+1,data[i].r)sam.add(s[j]-‘a‘); r=data[i].r; data[i].ans=sam.cnt; } sort(data+1,data+Q+1,cmpid); re(i,1,Q)printf("%I64d\n",data[i].ans); } return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=500000; const LL Mod=23333333333333333LL; const int maxT=3000000; int N,M; char s[maxN+1000]; int sa[maxN+100],rank[maxN+100],height[maxN+100]; int wa[maxN+100],wb[maxN+100],table[maxN+100]; inline bool cmp(int *y,int a,int b,int len){return y[a]==y[b] && y[a+len]==y[b+len];} inline void da() { int i,j,k,p,tol,*x=wa,*y=wb; p=0;re(i,1,N)upmax(p,x[i]=s[i]); re(i,1,p)table[i]=0; re(i,1,N)table[x[i]]++; re(i,1,p)table[i]+=table[i-1]; red(i,N,1)sa[table[x[i]]--]=i; for(swap(x,y),p=x[sa[1]]=1,i=2;i<=N;i++)x[sa[i]]=cmp(y,sa[i],sa[i-1],0)?p:++p; for(j=1;p<N;j<<=1) { tol=0;re(i,N-j+1,N)y[++tol]=i; re(i,1,N)if(sa[i]-j>=1)y[++tol]=sa[i]-j; re(i,1,p)table[i]=0; re(i,1,N)table[x[y[i]]]++; re(i,1,p)table[i]+=table[i-1]; red(i,N,1)sa[table[x[y[i]]]--]=y[i]; for(swap(x,y),p=x[sa[1]]=1,i=2;i<=N;i++)x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p:++p; } re(i,1,N)rank[sa[i]]=i; for(i=1,k=0;i<=N-1;height[rank[i++]]=k) for(k=max(0,k-1),j=sa[rank[i]-1];s[i+k]==s[j+k];k++); } int lg2[maxN+100]; int RMQ[31][maxN+100]; inline int ask(int l,int r) { int h=lg2[r-l+1]; return min(RMQ[h][l],RMQ[h][r-two(h)+1]); } int t; int p[maxT+100];////注意范围 不是maxN int top; LL val[maxN+100],cnt[maxN+100]; inline LL solve() { LL res=0,sum=0;int i; top=0; re(i,2,t) { int v=ask(p[i-1]+1,p[i]); top++; val[top]=LL(v); cnt[top]=1; sum=(sum+LL(v))%Mod; while(top>=2 && val[top-1]>=val[top]) { sum=(sum-cnt[top-1]*(val[top-1]-val[top])%Mod)%Mod; val[top-1]=val[top]; cnt[top-1]+=cnt[top]; top--; } res=(res+sum)%Mod; } res=(res%Mod+Mod)%Mod; return res; } int main() { freopen("bzoj3879.in","r",stdin); freopen("bzoj3879.out","w",stdout); int i,j; N=gint();M=gint(); scanf("%s\n",s+1); s[++N]=‘ ‘; da(); lg2[1]=0;re(i,2,N)lg2[i]=lg2[i>>1]+1; re(i,1,N)RMQ[0][i]=height[i]; re(j,1,30)re(i,1,N)if(i+two(j-1)<=N) RMQ[j][i]=min(RMQ[j-1][i],RMQ[j-1][i+two(j-1)]); else RMQ[j][i]=RMQ[j-1][i]; re(i,1,M) { t=gint(); re(j,1,t)p[j]=gint(); re(j,1,t)p[j]=rank[p[j]]; sort(p+1,p+t+1); t=unique(p+1,p+t+1)-p-1; cout<<solve()<<endl; } return 0; }
spoj8222
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=250000; struct SAM { struct Tnode { int ch[26],fail,l,size; inline void clear(){mmst(ch,0);fail=l=size=0;} }sn[2*maxN+100]; int idx,last; inline void clear(){sn[idx=last=1].clear();} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; sn[end].l=sn[p].l+1; for(;p && !sn[p].ch[z];p=sn[p].fail)sn[p].ch[z]=end; if(!p) sn[end].fail=1; else { int q=sn[p].ch[z]; if(sn[p].l+1==sn[q].l) sn[end].fail=q; else { int nq=newnode(); sn[nq]=sn[q]; sn[q].fail=sn[end].fail=nq; sn[nq].l=sn[p].l+1; for(;p && sn[p].ch[z]==q;p=sn[p].fail)sn[p].ch[z]=nq; } } //for(p=end;p;p=sn[p].fail)sn[p].size++; } int du[2*maxN+100],head,tail,que[2*maxN+100]; inline void insert(char *s,int N) { int i; clear(); re(i,1,N)add(s[i]-‘a‘); int p=1; re(i,1,N){p=sn[p].ch[s[i]-‘a‘];sn[p].size++;} re(i,1,idx)du[i]=0; re(i,2,idx)du[sn[i].fail]++; head=0;tail=-1; re(i,1,idx)if(du[i]==0)que[++tail]=i; while(head<=tail) { int u=que[head++],fa=sn[u].fail; if(fa!=1) { sn[fa].size+=sn[u].size; du[fa]--; if(du[fa]==0) que[++tail]=fa; } } } }; SAM sam; int N; char s[maxN+100]; int F[maxN+100]; int main() { freopen("spoj8222.in","r",stdin); freopen("spoj8222.out","w",stdout); int i; scanf("%s\n",s+1);N=strlen(s+1); sam.insert(s,N); re(i,2,sam.idx)upmax(F[sam.sn[i].l],sam.sn[i].size); red(i,N-1,1)upmax(F[i],F[i+1]); re(i,1,N)printf("%d\n",F[i]); return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!=‘-‘ && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z==‘-‘){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-‘0‘,z=getchar()); return (neg)?-res:res; } const int maxN=600000; struct SAM { struct Splay_Node { Splay_Node *son[2],*fa,*path_parent; int isRev,val,add; inline Splay_Node(){son[0]=son[1]=fa=path_parent=0;isRev=val=add=0;} inline void down() { if(isRev) { swap(son[0],son[1]); if(son[0])son[0]->isRev^=1; if(son[1])son[1]->isRev^=1; isRev=0; } if(add!=0) { if(son[0])son[0]->add+=add,son[0]->val+=add; if(son[1])son[1]->add+=add,son[1]->val+=add; add=0; } } }; Splay_Node *root; inline void Splay_Rotate(Splay_Node *x,int flag) { Splay_Node *y=x->fa,*z=y->fa; x->path_parent=y->path_parent;y->path_parent=0; if(x->son[flag])x->son[flag]->fa=y;y->son[flag^1]=x->son[flag]; x->son[flag]=y;y->fa=x; x->fa=z;if(z)z->son[y==z->son[1]]=x; } inline void Splay(Splay_Node *x) { Splay_Node *y,*z; while(x->fa) { y=x->fa;z=y->fa; if(z)z->down();if(y)y->down();if(x)x->down(); if(!z){Splay_Rotate(x,x==y->son[0]);break;} int L=(x==y->son[0]),R=(y==z->son[0]); if(L==R){Splay_Rotate(y,L);Splay_Rotate(x,R);continue;} if(L!=R){Splay_Rotate(x,L);Splay_Rotate(x,R);continue;} } x->down(); } inline void LCT_Access(Splay_Node *x) { Splay_Node *y; for(y=0;x;y=x,x=x->path_parent) { Splay(x); x->down(); if(x->son[1]){x->son[1]->fa=0;x->son[1]->path_parent=x;} x->son[1]=y; if(y){y->fa=x;y->path_parent=0;} } } inline void LCT_Evert(Splay_Node *x) { LCT_Access(x); Splay(x); x->isRev^=1; x->down(); } inline void LCT_Link(Splay_Node *u,Splay_Node *v) { LCT_Evert(u); Splay(u); u->path_parent=v; } inline void LCT_Cut(Splay_Node *u,Splay_Node *v) { LCT_Evert(root); LCT_Access(u); LCT_Access(v); Splay(u); u->path_parent=0; } inline void LCT_Add(Splay_Node *u) { LCT_Evert(root); LCT_Access(u); Splay(u); u->val++;u->add++; u->down(); } inline int LCT_Ask(Splay_Node *u) { Splay(u); return u->val; } struct Tnode { int ch[26],fail,l;Splay_Node *pos; inline void clear(){mmst(ch,0);fail=l=0;pos=new Splay_Node;} }sn[2*maxN+100]; int idx,last; inline void clear(){sn[idx=last=1].clear();root=sn[1].pos;} inline int newnode(){sn[++idx].clear();return idx;} inline void add(int z) { int end=newnode(); int p=last; last=end; sn[end].l=sn[p].l+1; for(;p && !sn[p].ch[z];p=sn[p].fail)sn[p].ch[z]=end; if(!p) { sn[end].fail=1; LCT_Link(sn[end].pos,sn[sn[end].fail].pos); } else { int q=sn[p].ch[z]; if(sn[p].l+1==sn[q].l) { sn[end].fail=q; LCT_Link(sn[end].pos,sn[sn[end].fail].pos); } else { int nq=newnode(); Splay_Node *temp=sn[nq].pos; sn[nq]=sn[q]; sn[nq].pos=temp; sn[nq].pos->val=LCT_Ask(sn[q].pos);//注意,常错写成 sn[nq].pos->val=sn[q].pos->val sn[nq].l=sn[p].l+1; //注意不要把pos全部复制过来,但是pos的val要复制 LCT_Cut(sn[q].pos,sn[sn[q].fail].pos); sn[q].fail=sn[end].fail=nq; LCT_Link(sn[q].pos,sn[sn[q].fail].pos); LCT_Link(sn[end].pos,sn[sn[end].fail].pos); LCT_Link(sn[nq].pos,sn[sn[nq].fail].pos); for(;p && sn[p].ch[z]==q;p=sn[p].fail)sn[p].ch[z]=nq; } } LCT_Add(sn[end].pos); } }; SAM sam; const int maxQL=3000000; char s[maxQL+1000]; inline void decodewithmark(char *s,int mark) { int i; re(i,0,strlen(s+1)-1) { mark=(mark*131+i)%strlen(s+1); swap(s[i+1],s[mark+1]); } } int main() { freopen("bzoj2555.in","r",stdin); freopen("bzoj2555.out","w",stdout); int Q=gint(),i,mark=0; sam.clear(); scanf("%s\n",s+1); re(i,1,strlen(s+1))sam.add(s[i]-‘A‘); for(;Q;Q--) { char type[20]; scanf("%s%s\n",type+1,s+1); decodewithmark(s,mark); if(type[1]==‘A‘) re(i,1,strlen(s+1))sam.add(s[i]-‘A‘); else { int p=1,len,res=-1; re(i,1,strlen(s+1)) { int z=s[i]-‘A‘; if(sam.sn[p].ch[z]) p=sam.sn[p].ch[z]; else {res=0;break;} } if(res!=0)res=sam.LCT_Ask(sam.sn[p].pos); printf("%d\n",res); mark^=res; } } return 0; }
标签:
原文地址:http://www.cnblogs.com/maijing/p/4649468.html