bzoj 1251 裸splay
裸的splay,只需要注意 max[-1]:=-maxlongint 就行了,否则在update的时候子节点的
max值会在max[-1]里选
/************************************************************** Problem: 1251 User: BLADEVIL Language: Pascal Result: Accepted Time:16008 ms Memory:3448 kb****************************************************************///By BLADEVILconst sroot =-1;var n, m :longint; i :longint; a, father :array[-1..100010] of longint; k, l, r, v :longint; root :longint; max, size, tree :array[-1..100010] of longint; val :array[-1..100010] of longint; flag :array[-1..100010] of boolean; son :array[-1..100010,0..1] of longint; procedure swap(var a,b:longint);var c :longint;begin c:=a; a:=b; b:=c;end; function get_max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;procedure renew_add(x,v:longint);begin inc(tree[x],v); inc(val[x],v); inc(max[x],v);end;procedure renew_reverse(x:longint);begin swap(son[x,1],son[x,0]); flag[x]:=not flag[x];end; procedure update(x:longint);begin //if x=sroot then exit; max[x]:=get_max(tree[x],get_max(max[son[x,1]],max[son[x,0]])); size[x]:=size[son[x,1]]+size[son[x,0]]+1;end; function build(l,r:longint):longint;var mid :longint;begin mid:=(r+l) div 2; build:=mid; tree[mid]:=a[mid]; if l+1<=mid then begin son[mid,0]:=build(l,mid-1); father[son[mid,0]]:=mid; end; if mid<=r-1 then begin son[mid,1]:=build(mid+1,r); father[son[mid,1]]:=mid; end; update(mid);end;procedure push_down(x:longint);var l, r :longint;begin l:=son[x,0]; r:=son[x,1]; if flag[x] then begin if l<>-1 then renew_reverse(l); if r<>-1 then renew_reverse(r); flag[x]:=false; end; if val[x]<>0 then begin if l<>-1 then renew_add(l,val[x]); if r<>-1 then renew_add(r,val[x]); val[x]:=0; end;end; function find(x:longint):longint;var t :longint;begin t:=root; while true do begin push_down(t); if size[son[t,0]]+1=x then exit(t); if size[son[t,0]]+1>x then t:=son[t,0] else begin dec(x,size[son[t,0]]+1); t:=son[t,1]; end; end;end;procedure rotate(x,y:longint);var f :longint;begin push_down(x); f:=father[x]; father[son[x,y xor 1]]:=f; son[f,y]:=son[x,y xor 1]; if f=root then root:=x else if f=son[father[f],0] then son[father[f],0]:=x else son[father[f],1]:=x; father[x]:=father[f]; father[f]:=x; son[x,y xor 1]:=f; update(f); update(x);end;procedure splay(x,y:longint);var u, v :longint;begin while father[x]<>y do begin if father[father[x]]=y then rotate(x,ord(x=son[father[x],1])) else begin if son[father[x],0]=x then u:=1 else u:=-1; if son[father[father[x]],0]=father[x] then v:=1 else v:=-1; if u*v=1 then begin rotate(father[x],ord(x=son[father[x],1])); rotate(x,ord(x=son[father[x],1])); end else begin rotate(x,ord(x=son[father[x],1])); rotate(x,ord(x=son[father[x],1])); end; end; end; update(x);end; procedure add(l,r,v:longint);var p :longint;begin p:=find(l);splay(p,sroot); p:=find(r+2);splay(p,root); p:=son[son[root,1],0]; renew_add(p,v);end;procedure reverse(l,r:longint);var p :longint;begin p:=find(l);splay(p,sroot); p:=find(r+2);splay(p,root); p:=son[son[root,1],0]; renew_reverse(p);end;function ask_max(l,r:longint):longint;var p :longint;begin p:=find(l); splay(p,sroot); p:=find(r+2); splay(p,root); p:=son[son[root,1],0]; ask_max:=max[p];end; begin fillchar(son,sizeof(son),255); read(n,m); max[-1]:=-maxlongint; for i:=1 to n do a[i]:=0; inc(n); root:=build(0,n); father[root]:=sroot; for i:=1 to m do begin read(k); if k=1 then begin read(l,r,v); add(l,r,v); end else begin read(l,r); if k=2 then reverse(l,r) else writeln(ask_max(l,r)); end; end;end.
浙公网安备 33010602011771号