本来poj3468是到大水题,但是为了splay入门还是选了这道题。 编的很丑。。5000ms。。 program poj3468; var l,r,fa:array[0..100005] of longint; c,w,s,son:array[0..100005] of int64; n,task,i,j,k,o,t,ff,f,a,b,cc,root:longint; q:char; procedure update(i,f:longint;ll:boolean); begin j:=l[i];k:=r[i]; son[i]:=1+son[j]+son[k]; s[i]:=s[j]+s[k]+w[i]; if j<>0 then fa[j]:=i; if k<>0 then fa[k]:=i; fa[i]:=f; if f<>0 then if ll then l[f]:=i else r[f]:=i; end; procedure put(i:longint); begin j:=l[i];k:=r[i];o:=c[i];c[i]:=0; inc(c[j],o);inc(c[k],o); inc(w[j],o);inc(w[k],o); inc(s[j],son[j]*o);inc(s[k],son[k]*o); end; procedure up(i:longint); begin o:=fa[i];t:=fa[o]; if l[o]=i then begin l[o]:=r[i];r[i]:=o; update(o,i,false);update(i,t,l[t]=o); end else begin r[o]:=l[i];l[i]:=o; update(o,i,true); update(i,t,l[t]=o); end; end; procedure splay(i:longint); begin f:=fa[i];ff:=fa[f]; while f<>0 do begin if (ff<>0) and not ((l[f]=i)xor(l[ff]=f)) then up(f); up(i); f:=fa[i];ff:=fa[f]; end; root:=i; end; procedure find(i,rk:longint); begin if c[i]<>0 then put(i); if rk<=son[l[i]] then find(l[i],rk) else if rk=son[l[i]]+1 then splay(i) else find(r[i],rk-son[l[i]]-1); end; procedure maketree(ll,rr,f:longint;var p:longint); var i:longint; begin if ll>rr then begin p:=0;exit; end; i:=(ll+rr)>>1;p:=i; maketree(ll,i-1,i,l[i]); maketree(i+1,rr,i,r[i]); fa[i]:=f; s[i]:=s[l[i]]+s[r[i]]+w[i]; son[i]:=son[l[i]]+son[r[i]]+1; end; begin readln(n,task); for i:=1 to n do read(w[i+1]);readln; maketree(1,n+2,0,root); for task:=1 to task do begin read(q); if q='Q' then begin readln(a,b);inc(b,2); find(root,a);fa[r[a]]:=0; find(root,b);fa[b]:=a; root:=a;r[a]:=b; writeln(s[l[b]]); end else begin readln(a,b,cc);inc(b,2); find(root,a);fa[r[a]]:=0; find(root,b);fa[b]:=a; root:=a;r[a]:=b; i:=l[b]; inc(s[i],cc*son[i]); inc(c[i],cc);inc(w[i],cc); update(b,a,false);update(a,0,true); end; end; end.