# bzoj2555 SubString

**什么破题……

  1 /**************************************************************
2     Problem: 2555
3     User: hzoier
4     Language: C++
5     Result: Accepted
6     Time:9748 ms
7     Memory:47112 kb
8 ****************************************************************/
9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&((x)->p->ch[1]!=(x))))
13 #define dir(x) ((x)==(x)->p->ch[1])
14 using namespace std;
15 const int maxn=1200010,maxm=3000010;
16 struct node{
17     int key,lazy;
18     node *ch[2],*p;
19     node(int d=0):key(d),lazy(0){}
20     inline void pushdown(){
21         if(!lazy)return;
22         key+=lazy;
23         ch[0]->lazy+=lazy;
24         ch[1]->lazy+=lazy;
25         lazy=0;
26     }
27 }null[maxn];
28 void decode(char*,int,int);
29 void expand(int);
30 int travel(const char*);
31 node *access(node*);
33 void cut(node*);
34 void splay(node*);
35 void rot(node*,int);
36 int root,last,cnt=0,val[maxn]={0},par[maxn]={0},go[maxn][2]={{0}};
37 char s[maxm],c[maxn];
39 int main(){
40     null->ch[0]=null->ch[1]=null->p=null;
41     root=last=++cnt;
42     null[root].ch[0]=null[root].ch[1]=null[root].p=null;
43     null[root].key=1;
44     scanf("%d%s",&q,s);
45     n=strlen(s);
46     for(int i=0;i<n;i++)expand(s[i]-'A');
47     while(q--){
48         scanf("%s%s",c,s);
51         else{
52             printf("%d\n",ans=travel(s));
54         }
55     }
56     return 0;
57 }
58 void decode(char *s,int n,int mask){
59     for(int i=0;i<n;i++){
62     }
63 }
64 void expand(int c){
65     int p=last,np=++cnt;
66     val[np]=val[p]+1;
67     null[np].ch[0]=null[np].ch[1]=null[np].p=null;
68     null[np].key=1;
69     while(p&&!go[p][c]){
70         go[p][c]=np;
71         p=par[p];
72     }
73     if(!p){
74         par[np]=root;
76     }
77     else{
78         int q=go[p][c];
79         if(val[q]==val[p]+1){
80             par[np]=q;
82         }
83         else{
84             int nq=++cnt;
85             val[nq]=val[p]+1;
86             memcpy(go[nq],go[q],sizeof(go[q]));
87             null[nq].ch[0]=null[nq].ch[1]=null[nq].p=null;
88             par[nq]=par[q];
90             par[np]=par[q]=nq;
92             cut(null+q);
94             while(p&&go[p][c]==q){
95                 go[p][c]=nq;
96                 p=par[p];
97             }
98         }
99     }
100     last=np;
101 }
102 int travel(const char *c){
103     int x=root;
104     while(*c)x=go[x][*c++-'A'];
105     if(!x)return 0;
106     splay(null+x);
107     return null[x].key;
108 }
109 node *access(node *x){
110     node *y=null;
111     while(x!=null){
112         splay(x);
113         x->ch[1]=y;
114         y=x;
115         x=x->p;
116     }
117     return y;
118 }
120     splay(x);
121     x->p=y;
122     access(y)->lazy+=x->key;
123 }
124 void cut(node *x){
125     access(x);
126     splay(x);
127     x->ch[0]->lazy-=x->key;
128     x->ch[0]->p=null;
129     x->ch[0]=null;
130 }
131 void splay(node *x){
132     x->pushdown();
133     while(!isroot(x)){
134         if(!isroot(x->p))x->p->p->pushdown();
135         x->p->pushdown();
136         x->pushdown();
137         if(isroot(x->p)){
138             rot(x->p,dir(x)^1);
139             break;
140         }
141         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
142         else rot(x->p,dir(x)^1);
143         rot(x->p,dir(x)^1);
144     }
145 }
146 void rot(node *x,int d){
147     node *y=x->ch[d^1];
148     if((x->ch[d^1]=y->ch[d])!=null)y->ch[d]->p=x;
149     y->p=x->p;
150     if(!isroot(x))x->p->ch[dir(x)]=y;
151     (y->ch[d]=x)->p=y;
152 }
153 /*
154 操作都是向后添加字符，因此考虑后缀自动机。
155 又因为需要动态维护子树大小，因此用LCT维护。
156 */
View Code

233333333
posted @ 2017-02-13 20:48  AntiLeaf  阅读(139)  评论(0编辑  收藏  举报