传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=1014
题目大意
给定字符串,要求支持
1.求lcp
2.修改某一位字符
3.插入字符
题解
因为要插入,所以用Splay维护子树表示的字符串的HASH值,然后就是细节啦
求lcp二分即可
Splay写了1个半点,QAQAQ,再颓废就真废了XD
const
maxn=100010;
seed=131;
mmod=maxlongint;
var
w:array[-1..2*maxn,1..5]of longint; {1.左儿子2.右儿子3.父4.子树节点和5.点ord值}
hash,pow:array[-1..2*maxn]of longint;
i,j,k:longint;
n,m,a,b,len,root,leng:longint;
cha,ch:char;
procedure print(a:longint);
begin
if w[a,1]<>-1 then print(w[a,1]);
write(chr(w[a,5]));
if w[a,2]<>-1 then print(w[a,2]);
if a=root then writeln;
end;
procedure change(a:longint);
var ls,rs:longint;
begin
ls:=w[a,1]; rs:=w[a,2];
hash[a]:=(int64(hash[rs])+int64(hash[ls])*pow[w[rs,4]+1]+int64(w[a,5])*pow[w[rs,4]])mod mmod;
end;
function max(a,b:longint):longint;
begin if a>b then exit(a) else exit(b); end;
procedure rotate(a,kind:longint);
var b,unkind:longint;
begin
unkind:=kind xor 3; b:=w[a,3];
w[a,4]:=w[b,4]; w[b,4]:=1+w[w[a,unkind],4]+w[w[b,unkind],4];
w[w[a,unkind],3]:=b; w[b,kind]:=w[a,unkind];
w[a,3]:=w[b,3]; w[b,3]:=a; w[a,unkind]:=b;
if w[w[a,3],1]=b
then w[w[a,3],1]:=a
else w[w[a,3],2]:=a;
change(a); change(b);
end;
procedure splay(a,goal:longint);
var kind,unkind,b:longint;
begin
while w[a,3]<>goal do
begin
b:=w[a,3]; if w[b,1]=a then kind:=1 else kind:=2; unkind:=kind xor 3;
if w[b,3]=goal then rotate(a,kind)
else
if w[w[b,3],kind]=b
then begin rotate(b,kind); rotate(a,kind); end
else begin rotate(a,kind); rotate(a,unkind); end;
end;
if goal=-1 then root:=a;
end;
function find(pos:longint):longint;
var tt:longint;
begin
tt:=root;
while w[w[tt,1],4]<>pos-1 do
if w[w[tt,1],4]>=pos
then tt:=w[tt,1]
else begin dec(pos,w[w[tt,1],4]+1); tt:=w[tt,2]; end;
exit(tt);
end;
function check(a,b,c:longint):longint;
var t1,t2:longint;
begin
if c=0 then exit(1);
splay(find(a-1),-1); splay(find(a+c),root); t1:=hash[w[w[root,2],1]];
splay(find(b-1),-1); splay(find(b+c),root); t2:=hash[w[w[root,2],1]];
if t1=t2 then exit(1) else exit(0);
end;
function query(a,b:longint):longint;
var l,r,mid,ans:longint;
begin
l:=0; r:=leng+1-max(a,b)+1; ans:=0;
while l<=r do
begin
mid:=(l+r)>>1;
if check(a,b,mid)=1
then begin ans:=mid; l:=mid+1; end
else r:=mid-1;
end;
exit(ans);
end;
procedure insert(pos:longint; ch:char);
var tt,fa:longint;
begin
tt:=find(pos);
splay(tt,-1);
hash[root]:=(int64(hash[w[root,2]])+int64(ord(ch))*pow[w[w[root,2],4]]+int64(w[root,5])*pow[w[w[root,2],4]+1]+int64(hash[w[root,1]])*pow[w[w[root,2],4]+2])mod mmod;
inc(w[root,4]);
tt:=w[w[root,2],1]; fa:=w[root,2];
while tt<>-1 do
begin
hash[tt]:=(int64(hash[tt])+int64(ord(ch))*pow[w[tt,4]])mod mmod;
inc(w[tt,4]);
fa:=tt; tt:=w[tt,1];
end;
inc(len); w[len,1]:=-1; w[len,2]:=-1; w[len,3]:=fa; w[len,4]:=1; w[len,5]:=ord(ch); w[fa,1]:=len; hash[len]:=ord(ch);
splay(len,-1);
end;
procedure update(pos:longint; ch:char);
var tt:longint;
begin
tt:=find(pos);
splay(tt,-1);
w[root,5]:=ord(ch);
change(root);
end;
begin
pow[0]:=1;
for i:=1 to maxn do
pow[i]:=(int64(pow[i-1])*seed)mod mmod;
len:=2; root:=1;
w[1,1]:=-1; w[1,2]:=2; w[1,3]:=-1; w[1,4]:=2; w[1,5]:=ord('#'); hash[1]:=(ord('#')*seed+ord('#'))mod mmod;
w[2,1]:=-1; w[2,2]:=-1; w[2,3]:=1; w[2,4]:=1; w[2,5]:=ord('#'); hash[2]:=ord('#')mod mmod;
i:=0; leng:=0;
while not eoln do
begin
inc(i); inc(leng);
read(cha);
insert(i,cha);
end;
readln;
readln(m);
for i:=1 to m do
begin
read(cha);
case cha of
'Q':begin readln(a,b); writeln(query(a+1,b+1)); end;
'R':begin readln(a,ch,ch); update(a+1,ch); end;
'I':begin readln(a,ch,ch); insert(a+1,ch); inc(leng); end;
end;
end;
end.