Description
火星人最近研究了一种操作:求一个字串两个后缀的公共前缀。比方说,有这样一个字符串:madamimadam,
我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d a m 现在,火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串,与该字符串中第y个字符开始的字串,两个字串的公共前缀的长度。比方说,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4, 7) = 0 在研究LCQ函数的过程中,火星人发现了这样的一个关联:如果把该字符串的所有后缀排好序,就可以很快地求出LCQ函数的值;同样,如果求出了LCQ函数的值,也可以很快地将该字符串的后缀排好序。 尽管火星人聪明地找到了求取LCQ函数的快速算法,但不甘心认输的地球人又给火星人出了个难题:在求取LCQ函数的同时,还可以改变字符串本身。具体地说,可以更改字符串中某一个字符的值,也可以在字符串中的某一个位置插入一个字符。地球人想考验一下,在如此复杂的问题中,火星人是否还能够做到很快地求取LCQ函数的值。Input
第一行给出初始的字符串。第二行是一个非负整数M,表示操作的个数。接下来的M行,每行描述一个操作。操
作有3种,如下所示1、询问。语法:Qxy,x,y均为正整数。功能:计算LCQ(x,y)限制:1<=x,y<=当前字符串长度。2、修改。语法:Rxd,x是正整数,d是字符。功能:将字符串中第x个数修改为字符d。限制:x不超过当前字符串长度。3、插入:语法:Ixd,x是非负整数,d是字符。功能:在字符串第x个字符之后插入字符d,如果x=0,则在字符串开头插入。限制:x不超过当前字符串长度Output
对于输入文件中每一个询问操作,你都应该输出对应的答案。一个答案一行。
Sample Input
madamimadam 7 Q 1 7 Q 4 8 Q 10 11 R 3 a Q 1 7 I 10 a Q 2 11
Sample Output
5 1 0 2 1
HINT
1、所有字符串自始至终都只有小写字母构成。
2、M<=150,0003、字符串长度L自始至终都满足L<=100,0004、询问操作的个数不超过10,000个。对于第1,2个数据,字符串长度自始至终都不超过1,000对于第3,4,5个数据,没有插入操作。
题解:
SPLAY!
维护字符串HASH值,二分答案并验证。
代码:
(写的常数有点大,并没有AC。)
1 var 2 v,h,p:array[-1..150005]of int64; 3 size,fa:array[-1..150005]of longint; 4 c:array[-1..150005,1..2]of longint; 5 chh:array[1..150005,0..1]of char; 6 pp:array[1..150005,1..2]of longint; 7 i,j,k,l,kk,n,m,root:longint; 8 ch,ch2:char; 9 s:ansistring; 10 function min(a,b:longint):longint; 11 begin 12 if a>b then exit(b); 13 exit(a); 14 end; 15 procedure up(x:longint); 16 begin 17 h[x]:=(h[c[x,1]])and 1073741823; 18 h[x]:=(h[x]+p[size[c[x,1]]]*v[x])and 1073741823; 19 h[x]:=(h[x]+h[c[x,2]]*p[size[c[x,1]]+1])and 1073741823; 20 size[x]:=size[c[x,1]]+1+size[c[x,2]]; 21 end; 22 function find(x,y:longint):longint; 23 begin 24 while true do 25 begin 26 if size[c[x,1]]>=y then x:=c[x,1] else 27 if size[c[x,1]]+1=y then exit(x) else 28 begin y:=y-size[c[x,1]]-1; x:=c[x,2]; end; 29 end; 30 end; 31 procedure left(x:longint;var xx:longint); 32 var k,y:longint; 33 begin 34 y:=fa[x]; 35 k:=c[x,2]; c[x,2]:=y; fa[k]:=y; c[y,1]:=k; 36 if y<>xx then 37 begin if c[fa[y],1]=y then c[fa[y],1]:=x else c[fa[y],2]:=x; end; 38 fa[x]:=fa[y]; fa[y]:=x; 39 if y=xx then xx:=x; 40 up(y); up(x); 41 end; 42 procedure right(x:longint;var xx:longint); 43 var k,y:longint; 44 begin 45 y:=fa[x]; 46 k:=c[x,1]; c[x,1]:=y; fa[k]:=y; c[y,2]:=k; 47 if y<>xx then 48 begin if c[fa[y],1]=y then c[fa[y],1]:=x else c[fa[y],2]:=x; end; 49 fa[x]:=fa[y]; fa[y]:=x; 50 if y=xx then xx:=x; 51 up(y); up(x); 52 end; 53 procedure splay(x:longint;var xx:longint); 54 var y,z:longint; 55 begin 56 while x<>xx do 57 begin 58 y:=fa[x]; z:=fa[y]; 59 if y=xx then 60 begin if c[y,1]=x then left(x,xx)else right(x,xx); end 61 else if c[y,1]=x then 62 begin 63 if c[z,1]=y then left(y,xx)else left(x,xx); 64 end else 65 begin 66 if c[z,1]=y then right(x,xx)else right(y,xx); 67 end; 68 end; 69 end; 70 function qq(k,l:longint):longint; 71 var x,y:longint; 72 begin 73 x:=find(root,k); y:=find(root,k+l+1); 74 splay(x,root); splay(y,c[x,2]); 75 exit(h[c[y,1]]); 76 end; 77 function solve(x,y:longint):longint; 78 var l,r,mid,i:longint; 79 begin 80 l:=find(root,x+1); r:=find(root,y+1); 81 if v[l]<>v[r] then exit(0); 82 l:=1; r:=min(n-x,n-y); 83 while l+1r then exit; 94 if l=r then 95 begin 96 if l=0 then v[l]:=0 else v[l]:=ord(s[l])-ord('a')+1; 97 h[l]:=v[l]; fa[l]:=f; size[l]:=1; 98 if l 0)and(chh[m,0]<>'Q')do dec(m);123 for i:=1 to m do124 begin125 case chh[i,0] of126 'Q':begin writeln(solve(pp[i,1],pp[i,2])); end;127 'R':begin128 l:=find(root,pp[i,1]+1); splay(l,root);129 v[l]:=ord(chh[i,1])-ord('a')+1; up(l);130 end;131 'I':begin132 l:=find(root,pp[i,1]+1); splay(l,root);133 l:=find(root,pp[i,1]+2); splay(l,c[root,2]);134 inc(n); c[l,1]:=n; fa[n]:=l;135 v[n]:=ord(chh[i,1])-ord('a')+1; c[n,1]:=-1; c[n,2]:=-1;136 up(n); up(fa[n]); up(root);137 end;138 end;139 end;140 end.