# BZOJ 1014 Splay+hash

View Code
  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <algorithm>
6
7 #define N 1000000
8
9 using namespace std;
10
11 char str[N];
12 int sz[N],son[N][2],fa[N];
13 int sum,n,root,cnt;
14 unsigned int hash[N],d[N],val[N];
15
16 inline void pushup(int x)
17 {
18     sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;
19     hash[x]=hash[son[x][0]]+val[x]*d[sz[son[x][0]]]+hash[son[x][1]]*d[sz[son[x][0]]+1];
20 }
21
22 inline void link(int x,int y,int c)
23 {
24     fa[x]=y; son[y][c]=x;
25 }
26
27 void rotate(int x,int c)
28 {
29     int y=fa[x];
33     pushup(y);
34 }
35
36 void splay(int x,int g)
37 {
38     while(fa[x]!=g)
39     {
40         int y=fa[x];
41         int cy=(son[fa[y]][1]==y),cx=(son[y][1]==x);
42         if(fa[y]==g) rotate(x,cx);
43         else
44         {
45             if(cx==cy) rotate(y,cy);
46             else rotate(x,cx);
47             rotate(x,cy);
48         }
49     }
50     pushup(x);
51     if(!g) root=x;
52 }
53
54 inline void newnode(int y,int &x,int sp)
55 {
56     x=++cnt; sp++;
57     fa[x]=y; sz[x]=1; val[x]=sp; hash[x]=sp;
58     son[x][0]=son[x][1]=0;
59 }
60
61 inline void build(int &x,int l,int r,int g)
62 {
63     if(l>r) return;
64     int mid=(l+r)>>1;
65     newnode(g,x,str[mid]-'a');
66     build(son[x][0],l,mid-1,x);
67     build(son[x][1],mid+1,r,x);
68     pushup(x);
69 }
70
71 inline void init()
72 {
73     scanf("%s",str+1); sum=strlen(str+1);
74     cnt=0;
75     newnode(0,root,26);
76     newnode(root,son[root][1],26);
77     sz[root]=2;
78     build(son[son[root][1]][0],1,sum,son[root][1]);
79     pushup(son[son[root][1]][0]);
80     pushup(son[root][1]);
81     pushup(root);
82 }
83
84 inline int find(int b)
85 {
86     int x=root;
87     while(x)
88     {
89         if(sz[son[x][0]]==b) return x;
90         else if(sz[son[x][0]]>b) x=son[x][0];
91         else b-=sz[son[x][0]]+1,x=son[x][1];
92     }
93 }
94
95 inline int gethash(int x,int y)
96 {
97     int fx,fy;
98     fx=find(x-1); fy=find(y+1);
99     splay(fx,0); splay(fy,fx);
100     return hash[son[fy][0]];
101 }
102
103 inline void QUERY(int x,int y)
104 {
105     int l=1,r=sum-y+1,mid,res=0;
106     int hx,hy;
107     while(l<=r)
108     {
109         mid=(l+r)>>1;
110         hx=gethash(x,x+mid-1);
111         hy=gethash(y,y+mid-1);
112         if(hx==hy) res=mid,l=mid+1;
113         else r=mid-1;
114     }
115     printf("%d\n",res);
116 }
117
118 inline void CHANGE(int x,int sp)
119 {
120     int fx=find(x);
121     splay(fx,0);
122     val[fx]=sp;
123     pushup(fx);
124 }
125
126 inline void INSERT(int x,int sp)
127 {
128     int fx=find(x),fy=find(x+1);
129     splay(fx,0); splay(fy,fx);
130     newnode(fy,son[fy][0],sp);
131     pushup(son[fy][0]); pushup(fy); pushup(fx);
132 }
133
134 inline void prep()
135 {
136     d[0]=1;
137     for(int i=1;i<500000;i++)
138         d[i]=d[i-1]*27;
139 }
140
141 inline void go()
142 {
143     prep();
144     init();
145     scanf("%d",&n);
146     int a,b;
147     while(n--)
148     {
149         scanf("%s",str);
150         if(str[0]=='Q')
151         {
152             scanf("%d%d",&a,&b);
153             if(a>b) swap(a,b);
154             if(a==b) printf("%d\n",sum-a+1);
155             else QUERY(a,b);
156         }
157         else if(str[0]=='R')
158         {
159             scanf("%d%s",&a,str);
160             CHANGE(a,str[0]-'a');
161         }
162         else
163         {
164             scanf("%d%s",&a,str);
165             INSERT(a,str[0]-'a');
166             sum++;
167         }
168     }
169 }
170
171 int main()
172 {
173     go();
174     return 0;
175 }

posted @ 2013-01-17 19:58  proverbs  阅读(829)  评论(1编辑  收藏  举报