标签:include ssi ken main struct simple top 答案 parent
第一行一个正整数Q
Q<=10^5
第二行一个长度为Q的字符串S
输出Q行,第i行表示前i个字符组成的字符串的答案
5
abaab
0
0
1
4
9
#include < cstdio > #define gec getchar #define FILE(F) freopen(F".in","r",stdin),freopen(F".out","w",stdout) #define DEBUG fprintf(stderr,"Passing [%s] in Line (%d)\n",__FUNCTION__,__LINE__) typedef long long ll; template inline void read(T&x) { x=0;bool f=0;char c=gec(); for(;c<‘0‘||c>‘9‘;c=gec())f=(c==‘-‘); for(;c>=‘0‘&&c<=‘9‘;c=gec())x=x*10+c-‘0‘; x=f?-x:x; } const int MAXN(100010),MP(1e9+7); int n;char str[MAXN]; void plus(int &x,int y){x+=y;x-=x>=MP?MP:0;} namespace Force_LCT { struct LCT { int nx[2],fa; int step,right; int Sum_step,Tag,Sum;//Son need +Tag? }tr[MAXN<<1]; void swap(int &x,int &y){int t(x);x=y;y=t;} int which(int x){if(tr[tr[x].fa].nx[0]==x)return 0;if(tr[tr[x].fa].nx[1]==x)return 1;return -1;} void push(int x) { if(!tr[x].Tag)return; plus(tr[tr[x].nx[0]].Tag,tr[x].Tag); plus(tr[tr[x].nx[0]].right,tr[x].Tag); plus(tr[tr[x].nx[0]].Sum,(ll)tr[x].Tag*tr[tr[x].nx[0]].Sum_step%MP); plus(tr[tr[x].nx[1]].Tag,tr[x].Tag); plus(tr[tr[x].nx[1]].right,tr[x].Tag); plus(tr[tr[x].nx[1]].Sum,(ll)tr[x].Tag*tr[tr[x].nx[1]].Sum_step%MP); tr[x].Tag=0; } void update(int x) { tr[x].Sum=((ll)tr[x].step*tr[x].right)%MP; tr[x].Sum_step=tr[x].step; if(tr[x].nx[0])plus(tr[x].Sum,tr[tr[x].nx[0]].Sum),plus(tr[x].Sum_step,tr[tr[x].nx[0]].Sum_step); if(tr[x].nx[1])plus(tr[x].Sum,tr[tr[x].nx[1]].Sum),plus(tr[x].Sum_step,tr[tr[x].nx[1]].Sum_step); } void rotate(int x) { int fa=tr[x].fa,fafa=tr[fa].fa,fd=which(fa),xd=which(x); tr[tr[x].nx[xd^1]].fa=fa; tr[fa].nx[xd]=tr[x].nx[xd^1]; tr[x].nx[xd^1]=fa;tr[fa].fa=x; tr[x].fa=fafa;if(fd!=-1)tr[fafa].nx[fd]=x; update(fa); } int st[MAXN<<1],tp; void splay(int x) { st[tp=1]=x; for(int t=x;which(t)!=-1;t=tr[t].fa)st[++tp]=tr[t].fa; while(tp)push(st[tp--]); while(which(x)!=-1) { int fa=tr[x].fa; if(which(fa)!=-1) rotate( which(x)^which(fa)? fa : x ); rotate(x); } update(x); } void access(int x) { for(int t=0;x;t=x,x=tr[x].fa) { splay(x); tr[x].nx[1]=t; update(x); } } void cut(int x,int y)//x‘s fa is y { access(x); splay(y); tr[y].nx[1]=0; update(y); tr[x].fa=0; } void link(int x,int y)//x‘s fa is y { splay(y); tr[x].fa=y; } } namespace Force_SAM { using namespace Force_LCT; struct SAM { int nx[26],pre,step,right; }sam[MAXN<<1];int top=1,now=1,root=1,last,lastson; void New(int x) { tr[x].right=sam[x].right; tr[x].step=sam[x].step-sam[sam[x].pre].step; update(x); } void entend(int x,int &S,int num) { last=now; now=++top; sam[now].step=sam[last].step+1; sam[now].right=1; for(;!sam[last].nx[x]&&last;last=sam[last].pre) sam[last].nx[x]=now; if(!last)sam[now].pre=root; else { lastson=sam[last].nx[x]; if(sam[lastson].step==sam[last].step+1)sam[now].pre=lastson; else { sam[++top]=sam[lastson]; sam[top].step=sam[last].step+1; splay(lastson); sam[top].right=sam[lastson].right=tr[lastson].right; New(top); link(top,sam[top].pre); cut(lastson,sam[lastson].pre); sam[now].pre=sam[lastson].pre=top; New(lastson); link(lastson,sam[lastson].pre); for(;sam[last].nx[x]==lastson&&last;last=sam[last].pre) sam[last].nx[x]=top; } } New(now); link(now,sam[now].pre); access(now); splay(now); S=tr[tr[now].nx[0]].Sum; plus(tr[tr[now].nx[0]].Tag,1); plus(tr[tr[now].nx[0]].right,1); plus(tr[tr[now].nx[0]].Sum,tr[tr[now].nx[0]].Sum_step); } int F[MAXN]; void Total() { New(1); for(int i=1;i<=n;i++) { entend(str[i]-‘a‘,F[i],i); plus(F[i],F[i-1]); } for(int i=1;i<=n;i++)plus(F[i],F[i-1]); for(int i=1;i<=n;i++)printf("%d\n",F[i]); } } int main() { read(n);scanf("%s",str+1); Force_SAM::Total(); return 0; }
51Nod 1600 Simple KMP SAM+LCT/树链剖分
标签:include ssi ken main struct simple top 答案 parent
原文地址:http://www.cnblogs.com/Oncle-Ha/p/7071456.html