codevs 4543 treap 模板

type rec=record
 lc,rc,v,rnd,size,w,fa:longint;
      end;

var
 n,root,tot,ans,opt,x,i,po:longint;
 tr:array[0..100000] of rec;

 procedure rotl(po:longint);
 var
  y:longint;
   begin
     y:=tr[po].rc;
     tr[po].rc:=tr[y].lc;
     if tr[y].lc>0 then tr[tr[y].lc].fa:=po;
     tr[y].fa:=tr[po].fa;
     if tr[po].fa=0 then root:=y else
       if po=tr[tr[po].fa].lc then
         tr[tr[po].fa].lc:=y else tr[tr[po].fa].rc:=y;
     tr[y].lc:=po;
     tr[po].fa:=y;
     tr[y].size:=tr[po].size;
     tr[po].size:=tr[tr[po].lc].size+tr[tr[po].rc].size+tr[po].w;
   end;

 procedure rotr(po:longint);
 var
  y:longint;
   begin
     y:=tr[po].lc;
     tr[po].lc:=tr[y].rc;
     if tr[y].rc>0 then tr[tr[y].rc].fa:=po;
     tr[y].fa:=tr[po].fa;
     if tr[po].fa=0 then root:=y else
       if po=tr[tr[po].fa].lc then
         tr[tr[po].fa].lc:=y else tr[tr[po].fa].rc:=y;
     tr[y].rc:=po;
     tr[po].fa:=y;
     tr[y].size:=tr[po].size;
     tr[po].size:=tr[tr[po].lc].size+tr[tr[po].rc].size+tr[po].w;
   end;

 procedure ins(x,po:longint);
   begin
     inc(tr[po].size);
     if x=tr[po].v then
       begin
        inc(tr[po].w);
        exit;
       end;

     if x<tr[po].v then
       begin
         if tr[po].lc=0 then
           begin
             inc(tot);
             tr[tot].fa:=po;
             tr[tot].v:=x;
             tr[tot].size:=1;
             tr[tot].w:=1;
             tr[tot].rnd:=random(10000)+1;
             tr[po].lc:=tot;
             if tr[tot].rnd<tr[po].rnd then rotr(po);
           end else
            begin
             ins(x,tr[po].lc);
             if tr[tr[po].lc].rnd<tr[po].rnd then rotr(po);
            end;
       end;

       if x>tr[po].v then
        begin
          if tr[po].rc=0 then
           begin
             inc(tot);
             tr[tot].fa:=po;
             tr[tot].v:=x;
             tr[tot].size:=1;
             tr[tot].w:=1;
             tr[tot].rnd:=random(10000)+1;
             tr[po].rc:=tot;
             if tr[tot].rnd<tr[po].rnd then rotl(po);
           end else
            begin
             ins(x,tr[po].rc);
             if tr[tr[po].rc].rnd<tr[po].rnd then rotl(po);
            end;
        end;
   end;

  function find(x,po:longint):longint;
    begin
      dec(tr[po].size);
      if x<tr[po].v then exit(find(x,tr[po].lc));
      if x>tr[po].v then exit(find(x,tr[po].rc));
      if x=tr[po].v then exit(po);
    end;

  procedure del(po:longint);
    begin
      while(tr[po].lc>0) or (tr[po].rc>0) do
        begin
          if tr[po].lc=0 then
            begin
              rotl(po);
              tr[tr[po].fa].size:=tr[tr[tr[po].fa].rc].size+tr[tr[po].lc].size+tr[tr[po].rc].size+tr[tr[po].fa].w;
              continue;
            end;

          if tr[po].rc=0 then
            begin
              rotr(po);
               tr[tr[po].fa].size:=tr[tr[tr[po].fa].lc].size+tr[tr[po].lc].size+tr[tr[po].rc].size+tr[tr[po].fa].w;
              continue;
            end;

          if tr[tr[po].lc].rnd>tr[tr[po].rc].rnd then
           begin
            rotl(po);
            tr[tr[po].fa].size:=tr[tr[tr[po].fa].rc].size+tr[tr[po].lc].size+tr[tr[po].rc].size+tr[tr[po].fa].w;
           end
            else
           begin
            rotr(po);
            tr[tr[po].fa].size:=tr[tr[tr[po].fa].lc].size+tr[tr[po].lc].size+tr[tr[po].rc].size+tr[tr[po].fa].w;
           end;
        end;

       if tr[tr[po].fa].lc=po then
         begin
           tr[tr[po].fa].lc:=0;
           tr[tr[po].fa].size:=tr[tr[tr[po].fa].rc].size+tr[tr[po].fa].w;
         end
       if tr[tr[po].fa].rc=po then
         begin
           tr[tr[po].fa].rc:=0;
           tr[tr[po].fa].size:=tr[tr[tr[po].fa].lc].size+tr[tr[po].fa].w;
         end;

         tr[po].size:=0;tr[po].w:=0;

       end;

  procedure num(x,po:longint);
   begin
     if x<=tr[tr[po].lc].size then
       begin
         num(x,tr[po].lc);
         exit;
       end;

     if x>tr[tr[po].lc].size+tr[po].w then
       begin
         num(x-tr[tr[po].lc].size-tr[po].w,tr[po].rc);
         exit;
       end;

     writeln(tr[po].v);
   end;

  procedure rank(x,po:longint);
    begin
      if x<tr[po].v then
        begin
          rank(x,tr[po].lc);
          exit;
        end;

      if x>tr[po].v then
        begin
          ans:=ans+tr[tr[po].lc].size+tr[po].w;
          rank(x,tr[po].rc);
          exit;
        end;

        ans:=ans+tr[tr[po].lc].size+1;
    end;

 procedure pre(x,po:longint);
   begin
     if po=0 then exit;
     if (tr[po].v<x) then
       begin
         ans:=tr[po].v;
         pre(x,tr[po].rc);
       end else pre(x,tr[po].lc);
   end;

 procedure suc(x,po:longint);
   begin
     if po=0 then exit;
     if (tr[po].v>x) then
       begin
         ans:=tr[po].v;suc(x,tr[po].lc);
       end else  suc(x,tr[po].rc);
   end;

  begin

    randomize;
    read(n);


    for i:=1 to n do
      begin
        read(opt,x);
        if opt=1 then
          begin
            if tr[root].w=0 then
              begin
                inc(tot);
                tr[tot].v:=x;tr[tot].size:=1;tr[tot].w:=1;
                tr[tot].rnd:=random(10000)+1;
                root:=tot;
              end else ins(x,root);
          end;
        if opt=2 then begin po:=find(x,root);if tr[po].w>1 then begin dec(tr[po].w);continue;end;del(po); end;
        if opt=3 then begin ans:=0;rank(x,root); writeln(ans);end;
        if opt=4 then num(x,root);
        if opt=5 then begin pre(x,root); writeln(ans); end;
        if opt=6 then begin suc(x,root); writeln(ans); end;
      end;


  end.

------------------------------------------------------

非旋treap

CODECHEF LTIME16 CHEFC

#include <cstdio>
#include <algorithm>
#define LL long long 
using namespace std;

  int a[200001],T,n,root,q;

  struct treenode{
      int lc,rc,lv,rv,v,ans,size;
  }tr[200001];

  void update(int po){
      if (!tr[po].lc) tr[po].lv=tr[po].v;else tr[po].lv=tr[tr[po].lc].lv;
      if (!tr[po].rc) tr[po].rv=tr[po].v;else tr[po].rv=tr[tr[po].rc].rv;
      
      tr[po].ans=tr[tr[po].lc].ans+tr[tr[po].rc].ans;
      if (tr[po].lc) tr[po].ans+=tr[po].v!=tr[tr[po].lc].rv;
      if (tr[po].rc) tr[po].ans+=tr[po].v!=tr[tr[po].rc].lv;
      
      tr[po].size=tr[tr[po].lc].size+tr[tr[po].rc].size+1;
  }

  int build(int l,int r){
      int mid=(l+r)>>1;
      tr[mid].v=a[mid];tr[mid].size=tr[mid].ans=0;tr[mid].lc=tr[mid].rc=0;
      if (l==r){
        tr[mid].lv=tr[mid].rv=tr[mid].v;tr[mid].size=1;
        return(mid);    
    }
      
      if (l!=mid) tr[mid].lc=build(l,mid-1);
      if (r!=mid) tr[mid].rc=build(mid+1,r);
      update(mid);
      return(mid);
  }

  void split(int po,int &root1,int &root2,int k){
      if (tr[tr[po].lc].size==k){
        root1=tr[po].lc;root2=po;
        tr[po].lc=0;
        update(po);
        return;
    }
    if (tr[tr[po].lc].size==k-1){
      root1=po;root2=tr[po].rc;
      tr[po].rc=0;
      update(po);
      return;
    }
    
    if (k<=tr[tr[po].lc].size){
      split(tr[po].lc,root1,root2,k);
      tr[po].lc=root2;
      update(po);
      root2=po;    
    }else{
      split(tr[po].rc,root1,root2,k-tr[tr[po].lc].size-1);
      tr[po].rc=root1;
      update(po);
      root1=po;
    }
  }

  int merge(int po1,int po2){
      if (po1==0||po2==0) return(po1|po2);
      
      if ((LL)rand()*tr[po1].size>(LL)rand()*tr[po2].size){
        tr[po1].rc=merge(tr[po1].rc,po2);
      update(po1);
      return(po1);    
    }else{
      tr[po2].lc=merge(po1,tr[po2].lc);
      update(po2);
      return(po2);
    }
  }

  void dfs_show(int po){
      if (tr[po].lc) dfs_show(tr[po].lc);
      printf("%d ",tr[po].v);
      if (tr[po].rc) dfs_show(tr[po].rc);
  }

  int main(){      
      scanf("%d",&T);
      while (T--){
        scanf("%d",&n);
      for (int i=1;i<=n;i++) scanf("%d",&a[i]);
      root=build(1,n);
      
      scanf("%d",&q);
      for (int i=1;i<=q;i++){
          int opt,l,r;
          scanf("%d%d%d",&opt,&l,&r);
          int root1,root2,root3;
          split(root,root1,root2,l-1);
        
          split(root2,root2,root3,r-l+1);
          
          if (opt==2){
            root1=merge(root1,root3);
          root=merge(root2,root1);
        }else{
          printf("%d\n",tr[root2].ans+1);
          root2=merge(root2,root3);
          root=merge(root1,root2);    
        }
      }
    }
  }

 

posted @ 2016-02-24 14:03  z1j1n1  阅读(178)  评论(0编辑  收藏  举报