建树时每棵子树的哈希值集中在根节点上,即h[x]=(h[left[x]]+v[x]*p[size[left]]+h[r]*p[size[left]+1])%mod
吐槽:这题交了很多遍,都是RE,然后我才知道BZOJ上用cin会RE......
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std;
9 #define MAXN 150010
10 #define ll long long
11 #define mod 9875321
12 int n,m,rt,sz,p[MAXN],c[MAXN][2],fa[MAXN],size[MAXN],h[MAXN],v[MAXN];
13 char ch[MAXN];
14 namespace INIT
15 {
16 inline int read()
17 {
18 int x=0,f=1; char ch=getchar();
19 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
20 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
21 return x*f;
22 }
23 }using namespace INIT;
24 namespace SPLAY
25 {
26 void updata(int x)
27 {
28 int l=c[x][0],r=c[x][1];
29 size[x]=size[l]+size[r]+1;
30 h[x]=h[l]+(ll)v[x]*p[size[l]]%mod+(ll)p[size[l]+1]*h[r]%mod;
31 h[x]%=mod;
32 }
33 void rotate(int x,int &k)
34 {
35 int y=fa[x],z=fa[y],l,r;
36 if(c[y][0]==x) l=0; else l=1; r=l^1;
37 if(y==k) k=x;
38 else {if(c[z][0]==y) c[z][0]=x; else c[z][1]=x;}
39 fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
40 c[y][l]=c[x][r]; c[x][r]=y;
41 updata(y); updata(x);
42 }
43 void Splay(int x,int &k)
44 {
45 while(x!=k)
46 {
47 int y=fa[x],z=fa[y];
48 if(y!=k)
49 {
50 if((c[y][0]==x)^(c[z][0]==y)) rotate(x,k);
51 else rotate(y,k);
52 }
53 rotate(x,k);
54 }
55 }
56 void build(int k,int l,int r)
57 {
58 if(l>r) return;
59 if(l==r)
60 {
61 v[l]=h[l]=ch[l]-'a'+1;
62 fa[l]=k; size[l]=1;
63 if(l0]=l;
64 else c[k][1]=l;
65 return;
66 }
67 int mid=(l+r)/2;
68 build(mid,l,mid-1); build(mid,mid+1,r);
69 v[mid]=ch[mid]-'a'+1; fa[mid]=k; updata(mid);
70 if(mid0]=mid;
71 else c[k][1]=mid;
72 }
73 int find(int k,int rank)
74 {
75 int l=c[k][0],r=c[k][1];
76 if(size[l]+1==rank) return k;
77 else if(size[l]>=rank) return find(l,rank);
78 else return find(r,rank-size[l]-1);
79 }
80 int check(int k,int val)
81 {
82 int x=find(rt,k),y=find(rt,k+val+1);
83 Splay(x,rt); Splay(y,c[x][1]);
84 int z=c[y][0];
85 return h[z];
86 }
87 int ask(int x,int y)
88 {
89 int l=1,r=min(sz-x,sz-y)-1,ans=0;
90 while(l<=r)
91 {
92 int mid=(l+r)/2;
93 if(check(x,mid)==check(y,mid)) {l=mid+1; ans=mid;}
94 else r=mid-1;
95 }
96 return ans;
97 }
98 void insert(int k,int val)
99 {
100 int x=find(rt,k+1),y=find(rt,k+2);
101 Splay(x,rt); Splay(y,c[x][1]);
102 int z=++sz; c[y][0]=z; fa[z]=y; v[z]=val;
103 updata(z); updata(y); updata(x);
104 }
105 }using namespace SPLAY;
106 int main()
107 {
108 //freopen("cin.in","r",stdin);
109 //freopen("cout.out","w",stdout);
110 scanf("%s",ch+2);
111 n=strlen(ch+2); p[0]=1;
112 for(int i=1;i<=MAXN;i++) p[i]=p[i-1]*27%mod;
113 build(0,1,n+2); rt=(n+3)/2; sz=n+2;
114 m=read(); int x,y;
115 char s[2],d[2];
116 for(int i=1;i<=m;i++)
117 {
118 scanf("%s",s+1); x=read();
119 if(s[1]=='Q') {y=read(); printf("%d\n",ask(x,y));}
120 if(s[1]=='R') {scanf("%s",d+1); x=find(rt,x+1); Splay(x,rt); v[rt]=d[1]-'a'+1; updata(rt);}
121 if(s[1]=='I') {scanf("%s",d+1); insert(x,d[1]-'a'+1);}
122 }
123 return 0;
124 }
1 #include
2 using namespace std;
3 char ch[5]={'Q','R','I'};
4 int main()
5 {
6 freopen("cin.in","w",stdout);
7 srand(time(NULL));
8 int n=100;
9 for(int i=1;i<=n;i++) printf("%c",(char)('a'+rand()%26));
10 printf("\n");
11 int m=1500;
12 printf("%d\n",m);
13 for(int i=1;i<=m;i++)
14 {
15 char f=ch[rand()%3];
16 if(f=='Q') {printf("%c %d %d\n",f,rand()%n+1,rand()%n+1);}
17 if(f=='R') {printf("%c %d %c\n",f,rand()%n+1,(char)('a'+rand()%26));}
18 if(f=='I') {printf("%c %d %c\n",f,rand()%n+1,(char)('a'+rand()%26));}
19 }
20 return 0;
21 }