zoukankan      html  css  js  c++  java
  • BZOJ 3196

    program bzoj3196;
    const inf=100000000;
        maxn=200001;
        maxm=3000001;
    
    var n,m,time,temp:longint;
        root,a:array [0..maxn] of longint;
        left,right,rnd,v,s,w:array [0..maxm] of longint;
    
    procedure update(now:longint);
    begin
        s[now]:=s[left[now]]+s[right[now]]+w[now];
    end;
    
    procedure rightturn(var now:longint);
    var t:longint;
    begin
        t:=left[now];
        left[now]:=right[t];
        right[t]:=now;
        s[t]:=s[now];
        update(now);
        now:=t;
    end;
    
    procedure leftturn(var now:longint);
    var t:longint;
    begin
        t:=right[now];
        right[now]:=left[t];
        left[t]:=now;
        s[t]:=s[now];
        update(now);
        now:=t;
    end;
    
    procedure insert(var now:longint; num:longint);
    begin
      if now=0 then 
        begin
          inc(time);
          now:=time;
          w[now]:=1;
          s[now]:=w[now];
          v[now]:=num;
          rnd[now]:=random(inf);
          exit;
        end;
       inc(s[now]);
       if num=v[now] then inc(w[now])
       else if num<v[now] then 
          begin
            insert(left[now],num);
              if rnd[left[now]]<rnd[now] then rightturn(now);
          end
        else  
          begin
            insert(right[now],num);
            if rnd[right[now]]<rnd[now] then leftturn(now);
          end;
    end;
    
    procedure del(var now:longint; num:longint);
    begin
      if v[now]=num then 
        begin
          if w[now]>1 then 
            begin
              dec(w[now]);
              dec(s[now]);
              exit;
            end;
          if left[now]*right[now]=0 then 
            now:=left[now]+right[now]
          else 
            if rnd[left[now]]<rnd[right[now]] then 
              begin
                rightturn(now);
                del(now,num);
              end
          else   
            begin
              leftturn(now);
              del(now,num);
            end
        end
       else  
         if num<v[now] then 
           begin
             del(left[now],num);
             dec(s[now]);
           end
        else 
          begin
            del(right[now],num);
            dec(s[now]);
          end;
    end;
    
    procedure build(now,l,r,x,num:longint);
    var mid:longint;
    begin
      insert(root[now],num);
      if l=r then exit;
      mid:=(l+r) shr 1;
      if x<=mid then build(now<<1,l,mid,x,num)
      else build(now<<1 or 1,mid+1,r,x,num);
    end;
    
    procedure ask_rank(now,num:longint);
    begin
      if now=0 then exit;
      if num=v[now] then 
        begin
          inc(temp,s[left[now]]);
          exit;
        end
      else
          if num<v[now] then
          ask_rank(left[now],num)
      else
        begin
          inc(temp,s[left[now]]+w[now]);
          ask_rank(right[now],num);
        end;
    end;
    
    procedure get_rank(now,l,r,x,y,num:longint);
    var mid:longint;
    begin
      mid:=(l+r) shr 1;
      if (l=x) and (r=y) then 
        begin 
          ask_rank(root[now],num);
          exit;
        end;
      if mid>=y then get_rank(now<<1,l,mid,x,y,num)
      else if mid<x then get_rank(now<<1 or 1,mid+1,r,x,y,num)
      else
        begin
          get_rank(now<<1,l,mid,x,mid,num);
          get_rank(now<<1 or 1,mid+1,r,mid+1,y,num);
        end;
    end;
    
    procedure get_index(x,y,z:longint);
    var l,r,ans,mid:longint;
    begin
      l:=0; r:=inf;
      while l<=r do
        begin
          mid:=(l+r) shr 1;
          temp:=1;
          get_rank(1,1,n,x,y,mid);
          if temp<=z then 
            begin
              l:=mid+1;
              ans:=mid;
            end
          else 
            r:=mid-1;
        end;
      writeln(ans);
    end;
    
    procedure change(now,l,r,x,num,y:longint);
    var mid:longint;
    begin
      del(root[now],y);
      insert(root[now],num);
      if l=r then exit;
      mid:=(l+r) shr 1;
      if x<=mid then change(now<<1,l,mid,x,num,y)
      else change(now<<1 or 1,mid+1,r,x,num,y);
    end;
    
    function max(x,y:longint):longint;
    begin
      if x>y then exit(x)
      else exit(y);
    end;
    
    function min(x,y:longint):longint;
    begin
      if x<y then exit(x)
      else exit(y);
    end;
    
    procedure before(now,num:longint);
    begin
      if now=0 then exit;
      if v[now]<num then 
        begin
          temp:=max(v[now],temp);
          before(right[now],num);
        end
      else 
        before(left[now],num);
    end;
    
    procedure after(now,num:longint);
    begin
      if now=0 then exit;
      if v[now]>num then 
        begin
          temp:=min(v[now],temp);
          after(left[now],num);
        end
      else 
        after(right[now],num);
    end;
    
    procedure ask_after(now,l,r,x,y,num:longint);
    var mid:longint;
    begin
      if (l=x) and (r=y) then 
        begin
          after(root[now],num);
          exit;
        end;
      mid:=(l+r) shr 1;
      if mid>=y then ask_after(now<<1,l,mid,x,y,num)
      else if mid<x then ask_after(now<<1 or 1,mid+1,r,x,y,num)
      else 
        begin
          ask_after(now<<1,l,mid,x,mid,num);
          ask_after(now<<1 or 1,mid+1,r,mid+1,y,num);
        end;
    end;
    
    procedure ask_before(now,l,r,x,y,num:longint);
    var mid:longint;
    begin
      if (l=x) and (r=y) then 
        begin
          before(root[now],num);
          exit;
        end;
      mid:=(l+r) shr 1;
      if mid>=y then ask_before(now<<1,l,mid,x,y,num)
      else if mid<x then ask_before(now<<1 or 1,mid+1,r,x,y,num)
      else 
        begin
          ask_before(now<<1,l,mid,x,mid,num);
          ask_before(now<<1 or 1,mid+1,r,mid+1,y,num);
        end;
    end;
    
    procedure main;
    var i,x,y,now,f:longint;
    begin
      read(n,m);
      for i:=1 to n do read(a[i]);
      for i:=1 to n do build(1,1,n,i,a[i]);
      for i:=1 to m do
        begin
          read(f);
          case f of 
            1:
              begin
                read(x,y,now);
                temp:=1;
                get_rank(1,1,n,x,y,now);
                writeln(temp);
              end;
            2:
              begin
                read(x,y,now);
                get_index(x,y,now);
              end;
            3:
              begin
                read(x,y);
                change(1,1,n,x,y,a[x]);
                a[x]:=y;
              end;
            4:
              begin
                read(x,y,now);
                temp:=0;
                ask_before(1,1,n,x,y,now);
                writeln(temp);
              end;
            5:
              begin
                read(x,y,now);
                temp:=inf;
                ask_after(1,1,n,x,y,now);
                writeln(temp);
              end;
          end;
        end;
    end;
    
    begin
      main;
    end.
  • 相关阅读:
    《高校大学生就业指导工作项目化管理研究》随笔
    《大学生就业网络信息服务模式研究》随笔
    文献随笔目录第五周
    申怡-《后危机时代大学生就业趋向调查研究》随笔
    文献随笔目录第四周
    《多媒体环境下大学生就业指导创新研究》随笔
    《企业参与大学生职业生涯规划对大学生就业能力的研究》随笔
    《高校就业服务信息交流平台构建研究》随笔
    《基于新媒体环境下创新高校就业创业指导工作的思考与探索》随笔
    《“双创”视阈下大学生就业教育研究》随笔
  • 原文地址:https://www.cnblogs.com/logichandsome/p/4054630.html
Copyright © 2011-2022 走看看