bzoj 1500 splay 【终极模板】 【pascal】

61 篇文章 0 订阅
5 篇文章 0 订阅

连打带差错一天就这样过去了orz orz orz

{$inline on}
const
        sroot=-1;
        maxn=100000000;
var
        n,m,root,tot,top:longint;
        p,q,t           :longint;
        i,j             :longint;
        ch              :char;
        s               :string;
        a,tree,size     :array[-1..500010] of longint;
        flag            :array[-1..500010] of boolean;
        father          :array[-1..500010] of longint;
        val             :array[-1..500010] of longint;
        sum,getmax,num  :array[-1..500010] of longint;
        maxl,maxr       :array[-1..500010] of longint;
        son             :array[-1..500010,0..1] of longint;
function max(a,b:longint):longint;inline;
begin
   if a>b then exit(a) else exit(b);
end;

procedure swap(var a,b:longint);inline;
var
        c:longint;
begin
   c:=a;a:=b;b:=c;
end;

procedure renew(x,y:longint);
begin
   if y=maxn then
   begin
      swap(son[x,1],son[x,0]);
      swap(maxl[x],maxr[x]);
      flag[x]:=not flag[x];
   end else
   begin
      tree[x]:=y;
      sum[x]:=y*size[x];
      if x<0 then
      begin
         getmax[x]:=y;
         maxl[x]:=y;
         maxr[x]:=y;
      end else
      begin
         getmax[x]:=sum[x];
         maxl[x]:=sum[x];
         maxr[x]:=sum[x];
      end;
      val[x]:=y;
   end;
end;

procedure update(x:longint);
begin
   size[x]:=size[son[x,0]]+size[son[x,1]]+1;
   sum[x]:=sum[son[x,0]]+sum[son[x,1]]+tree[x];
   maxl[x]:=max(maxl[son[x,0]],max(sum[son[x,0]]+tree[x],sum[son[x,0]]+tree[x]+maxl[son[x,1]]));
   maxr[x]:=max(maxr[son[x,1]],max(sum[son[x,1]]+tree[x],sum[son[x,1]]+tree[x]+maxr[son[x,0]]));
   getmax[x]:=max(tree[x],max(maxl[x],maxr[x]));
   getmax[x]:=max(getmax[x],max(getmax[son[x,0]],getmax[son[x,1]]));
   getmax[x]:=max(getmax[x],max(maxr[son[x,0]],maxl[son[x,1]])+tree[x]);
   getmax[x]:=max(getmax[x],maxr[son[x,0]]+maxl[son[x,1]]+tree[x]);
end;

function build(l,r:longint):longint;
var
        mid,t:longint;
begin
   t:=num[top];
   inc(top);
   build:=t;
   mid:=(l+r) >>1;
   tree[t]:=a[mid];
   if (l<=mid-1) then
   begin
      son[t,0]:=build(l,mid-1);
      father[son[t,0]]:=t;
   end;
   if (r>=mid+1) then
   begin
      son[t,1]:=build(mid+1,r);
      father[son[t,1]]:=t;
   end;
   update(t);
end;

procedure push_down(x:longint);
var
        l,r:longint;
begin
   l:=son[x,0]; r:=son[x,1];
   if val[x]<>maxn then
   begin
      if (l<>0) then renew(l,val[x]);
      if (r<>0) then renew(r,val[x]);
      val[x]:=maxn;
   end;
   if flag[x] then
   begin
      if (l<>0) then renew(l,maxn);
      if (r<>0) then renew(r,maxn);
      flag[x]:=false;
   end;
end;

procedure del_(x:longint);
var
       f:longint;
begin
   f:=father[x];
   while (x<>f) do
   begin
      if (son[x,0]<>0) then
      begin
         x:=son[x,0];continue;
      end;
      if (son[x,1]<>0) then
      begin
         x:=son[x,1];continue;
      end;
      //
      flag[x]:=false;
      val[x]:=maxn;
      dec(top);
      num[top]:=x;
      //
      if son[father[x],0]=x then son[father[x],0]:=0
       else son[father[x],1]:=0;
      x:=father[x];
   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 ro(x,y:longint);
var
        f:longint;
begin
   f:=father[x];
   son[f,y]:=son[x,y xor 1];
   father[son[x,y xor 1]]:=f;
   //
   if f=root then root:=x else
    if f=son[father[f],1] then son[father[f],1]:=x
     else son[father[f],0]:=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 ro(x,ord(x=son[father[x],1])) else
      begin
         if x=son[father[x],0] then u:=1 else u:=-1;
         if father[x]=son[father[father[x]],0] then v:=1 else v:=-1;
         if (u*v=1) then
         begin
            ro(father[x],ord(x=son[father[x],1]));
            ro(x,ord(x=son[father[x],1]));
         end else
         begin
            ro(x,ord(x=son[father[x],1]));
            ro(x,ord(x=son[father[x],1]));
         end;
      end;
   end;
   update(x);
end;

procedure insert(l,x:longint);
var
        p:longint;
begin
   p:=find(l+1);splay(p,sroot);
   p:=find(l+2);splay(p,root);
   son[son[root,1],0]:=x;
   father[x]:=son[root,1];
   update(son[root,1]);
   update(root);
end;

procedure delete(l,r:longint);
var
        p:longint;
begin
   p:=find(l);splay(p,sroot);
   p:=find(r+2);splay(p,root);
   del_(son[son[root,1],0]);
   son[son[root,1],0]:=0;
   update(son[root,1]);
   update(root);
end;

procedure make_same(l,r,c:longint);
var
        p:longint;
begin
   p:=find(l);splay(p,sroot);
   p:=find(r+2);splay(p,root);
   renew(son[son[root,1],0],c);
   update(son[root,1]);
   update(root);
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(p,maxn);
   update(son[root,1]);
   update(root);
end;

function get_sum(l,r:longint):longint;
var
        p:longint;
begin
   p:=find(l);splay(p,sroot);
   p:=find(r+2);splay(p,root);
   exit(sum[son[son[root,1],0]]);
end;

begin
   for i:=1 to 500000 do num[i]:=i;
   for i:=1 to 500000 do val[i]:=maxn;
   top:=1;
   size[0]:=0;
   tree[0]:=-maxn;
   getmax[0]:=-maxn;
   maxl[0]:=-maxn;
   maxr[0]:=-maxn;
   //
   read(n,m);
   for i:=2 to n+1 do read(a[i]);
   a[1]:=-maxn;a[n+2]:=-maxn;
   root:=build(1,n+2);
   father[root]:=sroot;
   tot:=n;
   readln;
   //
   for i:=1 to m do
   begin
      s:='';
      read(ch);
      while (ch<>' ') and (not eoln) do
      begin
         s:=s+ch;
         read(ch);
      end;
      if ch<>' ' then s:=s+ch;
      case s[3] of
         'S':
         begin
            read(p,n);
            inc(tot,n);
            for j:=1 to n do read(a[j]);
            t:=build(1,n);
            insert(p,t);
         end;
         'L':
         begin
            read(p,n);
            dec(tot,n);
            delete(p,p+n-1);
         end;
         'K':
         begin
            read(p,n,q);
            make_same(p,p+n-1,q);
         end;
         'V':
         begin
            read(p,n);
            reverse(p,p+n-1);
         end;
         'T':
         begin
            read(p,n);
            writeln(get_sum(p,p+n-1));
         end;
         'X':writeln(getmax[root]);
      end;
      readln;
   end;
end.
——by Eirlys

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值