zoukankan      html  css  js  c++  java
  • 平衡树有关题目小结

    一、P2042 [NOI2005]维护数列

                                                                                              

      要求维护一个数列,支持以上几种操作。

      此题可以看作平衡树的一个大模板,由于是区间问题,所以用splay或者fhqtreap,我用了fhqtreap(写起来太舒服了)。

      数据范围:  

      你可以认为在任何时刻,数列中至少有 1 个数。

      输入数据一定是正确的,即指定位置的数在数列中一定存在。

      50%的数据中,任何时刻数列中最多含有 30 000 个数;

      100%的数据中,任何时刻数列中最多含有 500 000 个数。

      100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。

      100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 。

      

      1.插入和删除tot个数:因为这题时间卡的很紧,所以不能使用比较方便的那种O(nlogn)方式插入,因为此题是区间,所以插入的数据必是单调插入,所以此处使用笛卡尔树的建树方式,复杂度为O(n),因为需要用到栈,此处建议手写栈,STL太慢了(STL一生黑QAQ,真香)。这题还得用读入优化,不知是  。删除的话直接将区间提取出来删掉就可以了。但是,此处有个问题,删除的空间需要回收,因为只有128M内存,貌似最多也就开1e6,但是,数据范围告诉了数列中最多有5e5个数字,所以删除的时候就要求空间回收,下次插入的时候要插到这些空间中(再来个栈就完事了,小问题)。

      2.修改和反转:像线段树一样就好了,打个标记,然后再访问的时候往下推。

      3.求和求最大子序列,维护sum,lmax,rmax,mmax就行了。(%%%)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAX=5e5+20,INF=0x7fffffff;
      4 struct ppp{
      5     int val,ch[2],rnd,sum,lmax,rmax,mmax,size;
      6     int change,reverse;
      7 }treap[MAX];
      8 int n,m,tot,root,name[MAX],st[MAX];
      9 int read() 
     10 {
     11     int tmp=0,fh=1; char c=getchar();
     12     while ((c<'0'||c>'9')&&c!='-') c=getchar();
     13     if (c=='-') fh=-1,c=getchar();
     14     while (c>='0'&&c<='9') tmp=tmp*10+c-48,c=getchar();
     15     return tmp*fh;
     16 }
     17 inline int NEW(int val)
     18 {
     19     int p=name[tot--];
     20     treap[p]=(ppp){val,0,0,rand(),0,0,0,0,0,0,0};
     21     treap[p].val=val;
     22     treap[p].rnd=rand();
     23     treap[p].sum=val;
     24     treap[p].lmax=treap[p].rmax=treap[p].mmax=val;
     25     treap[p].size=1;
     26     treap[p].change=INF;
     27     return p;
     28 }
     29 inline void reuse(int p)
     30 {
     31     if(!p)    return ;
     32     name[++tot]=p;
     33     reuse(treap[p].ch[0]);
     34     reuse(treap[p].ch[1]);
     35 }
     36 inline void down(int p)
     37 {
     38     if(p==0)    return;
     39     if(treap[p].reverse)
     40     {
     41         treap[p].reverse=0;
     42         swap(treap[p].ch[1],treap[p].ch[0]);
     43         treap[treap[p].ch[0]].reverse^=1;
     44         treap[treap[p].ch[1]].reverse^=1;
     45         swap(treap[p].lmax,treap[p].rmax);
     46     }
     47     if(treap[p].change!=INF)
     48     {
     49         int k=treap[p].change;
     50         treap[p].change=INF;
     51         treap[p].rmax=treap[p].mmax=treap[p].lmax=(k>=0? k*treap[p].size:k);
     52         treap[p].sum=treap[p].size*k;
     53         treap[p].val=k;
     54         treap[treap[p].ch[0]].change=k;
     55         treap[treap[p].ch[1]].change=k;
     56     }
     57 }
     58 inline void update(int p)
     59 {
     60     down(treap[p].ch[0]);
     61     down(treap[p].ch[1]);
     62     treap[p].sum=treap[p].val+treap[treap[p].ch[0]].sum+treap[treap[p].ch[1]].sum;
     63     treap[p].size=treap[treap[p].ch[0]].size+treap[treap[p].ch[1]].size+1;
     64     treap[p].lmax=max(treap[treap[p].ch[0]].lmax,treap[treap[p].ch[0]].sum+treap[p].val+max(0,treap[treap[p].ch[1]].lmax));
     65     treap[p].rmax=max(treap[treap[p].ch[1]].rmax,treap[treap[p].ch[1]].sum+treap[p].val+max(0,treap[treap[p].ch[0]].rmax));
     66     treap[p].mmax=max(max(treap[treap[p].ch[0]].mmax,treap[treap[p].ch[1]].mmax),treap[p].val+max(0,treap[treap[p].ch[0]].rmax)+max(0,treap[treap[p].ch[1]].lmax));
     67 }
     68 
     69 inline int build(int k)//笛卡尔树的建树方式 按照权值升序插入 O(n) 
     70 {
     71     int tem_root,top=0;
     72     tem_root=read();
     73     tem_root=NEW(tem_root);
     74     st[++top]=tem_root;
     75     for(int i=1;i<k;i++)//k-1 次循环 
     76     {
     77         int val;
     78         val=read();
     79         int p=NEW(val),last=0;
     80         while(top and treap[st[top]].rnd>treap[p].rnd)//小根堆 
     81         {
     82             treap[p].ch[0]=st[top];
     83             update(st[top]);
     84             top--;
     85         }
     86         if(top)
     87             treap[st[top]].ch[1]=p;
     88         else
     89             tem_root=p;
     90         st[++top]=p;
     91         update(p);
     92     }
     93     while(top)
     94     {
     95         update(st[top]);
     96         top--;
     97     }
     98     return tem_root;
     99 }
    100 inline void split(int now,int &x,int &y,int rank)
    101 {
    102     down(now);
    103     if(rank>=treap[now].size)
    104     {
    105         x=now,y=0;
    106         return ;
    107     }
    108     if(rank<=0)
    109     {
    110         y=now,x=0;
    111         return ;
    112     }
    113     if(rank<=treap[treap[now].ch[0]].size)
    114     {
    115         y=now;
    116         split(treap[now].ch[0],x,treap[now].ch[0],rank);
    117     }
    118     else
    119     {
    120         x=now;
    121         split(treap[now].ch[1],treap[now].ch[1],y,rank-treap[treap[now].ch[0]].size-1);
    122     }
    123     update(now);
    124 }
    125 inline int merge(int x,int y)
    126 {
    127     down(x);down(y);
    128     if(x==0 or y==0)
    129         return x+y;
    130     if(treap[x].rnd<treap[y].rnd)
    131     {
    132         treap[x].ch[1]=merge(treap[x].ch[1],y);
    133         update(x);
    134         update(treap[x].ch[1]);
    135         return x;
    136     }
    137     else
    138     {
    139         treap[y].ch[0]=merge(x,treap[y].ch[0]);
    140         update(y);
    141         update(treap[y].ch[0]);
    142         return y;
    143     }
    144 }
    145 inline void remove(int pos,int num)
    146 {
    147     int x=0,y=0,z=0;
    148     split(root,x,y,pos-1);
    149     split(y,y,z,num);
    150     reuse(y);
    151     root=merge(x,z);
    152 }
    153 inline void insert(int pos,int num)
    154 {
    155     int x,y,z;
    156     split(root,x,y,pos);
    157     z=build(num);
    158     root=merge(merge(x,z),y);
    159 }
    160 inline void make_same(int pos,int num,int c)
    161 {
    162     int x=0,y=0,z=0;
    163     split(root,x,y,pos-1);
    164     split(y,y,z,num);
    165     treap[y].change=c;
    166     y=merge(y,z);
    167     root=merge(x,y);
    168 }
    169 inline void reverse(int pos,int num)
    170 {
    171     int x=0,y=0,z=0;
    172     split(root,x,y,pos-1);
    173     split(y,y,z,num);
    174     treap[y].reverse^=1;
    175     y=merge(y,z);
    176     root=merge(x,y);
    177 }
    178 inline void getsum(int pos,int sum)
    179 {
    180     int x=0,y=0,z=0;
    181     split(root,x,y,pos-1);
    182     split(y,y,z,sum);
    183     printf("%d
    ",treap[y].sum);
    184     y=merge(y,z);
    185     root=merge(x,y);
    186 }
    187 inline void maxsum()
    188 {
    189     printf("%d
    ",treap[root].mmax);
    190 }
    191 int main()
    192 {
    193     //scanf("%d%d",&n,&m);
    194     n=read();m=read();
    195     for (int i=500010;i;i--) name[++tot]=i;
    196     treap[0].lmax=treap[0].rmax=treap[0].mmax=-INF;
    197     root=build(n);
    198     char opt[15];
    199     for(int i=1;i<=m;i++)
    200     {
    201         char c=getchar();
    202         while(c<'A' or c>'Z')    c=getchar();
    203         opt[0]=c;opt[1]=getchar();opt[2]=getchar();
    204         while((c>='A' and c<='Z') or c=='-')    c=getchar();
    205         if(opt[0]=='I')
    206         {
    207             int k=read(),jkl=read();
    208             //scanf("%d%d",&k,&jkl);
    209             insert(k,jkl);
    210         }
    211         else if(opt[0]=='D')
    212         {
    213             int  O=read(),P=read();
    214             //scanf("%d%d",&O,&P);
    215             remove(O,P);
    216         }
    217         else if(opt[2]=='K')
    218         {
    219             int  O=read(),P=read(),C=read();
    220             //scanf("%d%d%d",&O,&P,&C);
    221             make_same(O,P,C);
    222         }
    223         else if(opt[0]=='R')
    224         {
    225             int  O=read(),P=read();
    226             //scanf("%d%d",&O,&P);
    227             reverse(O,P);
    228         }
    229         else if(opt[0]=='G')
    230         {
    231             int  O=read(),P=read();
    232             //scanf("%d%d",&O,&P);
    233             getsum(O,P);
    234         }
    235         else
    236             maxsum();
    237     }
    238     return 0;
    239 }
    View Code

    二、P2596 [ZJOI2006]书架

      这题最大的问题就是要根据区间的内的编号来找到点的排名,记录父节点,记录每个值所在点的编号,然后递归求rank即可

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAX=8e4+30,INF=0x7fffffff;
      4 struct ppp{
      5     int val,ch[2],size,rand,fa;
      6 }treap[MAX];
      7 int n,m,tot,root,st[MAX],top,pic[MAX];
      8 inline int NEW(int val)
      9 {
     10     tot++;
     11     treap[tot].val=val;
     12     treap[tot].size=1;
     13     treap[tot].rand=rand();
     14     return tot;
     15 }
     16 inline void update(int p)
     17 {
     18     treap[p].size=treap[treap[p].ch[0]].size+treap[treap[p].ch[1]].size+1;
     19     if(treap[p].ch[0]!=0)
     20         treap[treap[p].ch[0]].fa=p;
     21     if(treap[p].ch[1]!=0)
     22         treap[treap[p].ch[1]].fa=p;
     23 }
     24 inline void split(int now,int &x,int &y,int rank)
     25 {
     26     if(rank<=0)
     27     {
     28         y=now,x=0;
     29         return ;
     30     }
     31     if(rank>=treap[now].size)
     32     {
     33         x=now,y=0;
     34         return ;
     35     }
     36     if(treap[treap[now].ch[0]].size>=rank)
     37     {
     38         y=now;
     39         split(treap[now].ch[0],x,treap[now].ch[0],rank);
     40     }
     41     else
     42     {
     43         x=now;
     44         split(treap[now].ch[1],treap[now].ch[1],y,rank-treap[treap[now].ch[0]].size-1);
     45     }
     46     update(now);
     47 }
     48 inline int merge(int x,int y)
     49 {
     50     if(x==0 or y==0)
     51         return x+y;
     52     if(treap[x].rand<treap[y].rand)
     53     {
     54         treap[x].ch[1]=merge(treap[x].ch[1],y);
     55         update(x);
     56         return x;
     57     }
     58     else
     59     {
     60         treap[y].ch[0]=merge(x,treap[y].ch[0]);
     61         update(y);
     62         return y;
     63     }
     64 }
     65 inline int build(int k)
     66 {
     67     int tem_root;
     68     scanf("%d",&tem_root);
     69     tem_root=NEW(tem_root);
     70     pic[treap[tem_root].val]=tem_root;
     71     st[++top]=tem_root;
     72     for(int i=1;i<k;i++)
     73     {
     74         int val;
     75         scanf("%d",&val);
     76         int p=NEW(val);
     77         pic[val]=p;
     78         int last=0;
     79         while(top and  treap[st[top]].rand>treap[p].rand)
     80         {
     81             //treap[p].ch[0]=st[top];
     82             last=st[top];
     83             update(st[top]);
     84             top--;
     85         }
     86         treap[p].ch[0]=last;
     87         if(top)
     88             treap[st[top]].ch[1]=p;
     89         else
     90             tem_root=p;
     91         st[++top]=p;
     92         update(p);
     93     }
     94     while(top)
     95     {
     96         update(st[top]);
     97         top--;
     98     }
     99     return tem_root;
    100 }
    101 inline int find(int p)
    102 {
    103     int fa=treap[p].fa;
    104     if(fa==0 or p==0)    return 0;
    105     int son=treap[fa].ch[1]==p;
    106     if(son)    return treap[treap[fa].ch[0]].size+1+find(fa);
    107     else    return find(fa);
    108 }
    109 inline int getrank(int p)
    110 {
    111     return find(p)+treap[treap[p].ch[0]].size+1;
    112 }
    113 int main()
    114 {
    115     scanf("%d%d",&n,&m);
    116     root=build(n);
    117     for(int i=1;i<=m;i++)
    118     {
    119         char s[10];
    120         int val;
    121         scanf("%s %d",s,&val);
    122         if(s[0]=='T')
    123         {
    124             int p=pic[val];
    125             int rank=getrank(p);
    126             int x,y,z;
    127             split(root,x,y,rank-1);
    128             split(y,z,y,1);
    129             root=merge(merge(z,x),y);
    130         }
    131         else if(s[0]=='B')
    132         {
    133             int p=pic[val];
    134             int rank=getrank(p);
    135             int x,y,z;
    136             split(root,x,y,rank-1);
    137             split(y,z,y,1);
    138             root=merge(merge(x,y),z);
    139         }
    140         else if(s[0]=='I')
    141         {
    142             int t;
    143             scanf("%d",&t);
    144             if(t==0)    continue;
    145             if(t==1)    t=0;
    146             
    147             int p=pic[val];
    148             int rank=getrank(p);
    149             int x,y,z,q;
    150             split(root,x,y,rank-1+t);
    151             split(y,z,y,1);
    152             split(y,q,y,1);
    153             root=merge(merge(x,q),merge(z,y));
    154         }
    155         else if(s[0]=='A')
    156         {
    157             int p=pic[val];
    158             int rank=getrank(p);
    159             printf("%d
    ",rank-1);
    160         }
    161         else if(s[0]=='Q')
    162         {
    163             int x,y,z;
    164             split(root,x,y,val-1);
    165             split(y,z,y,1);
    166             printf("%d
    ",treap[z].val);
    167             root=merge(merge(x,z),y);
    168         }
    169     }
    170     return 0;
    171 }
    View Code

    三、P3285 [SCOI2014]方伯伯的OJ

       无力吐槽,此题动态开点。。。debug了一整天,代码漏洞颇多。。。。QAQ
       此题一个收获:对于一段区间都要映射到某个值,可以取这个区间的最大值,将之映射(m)于val,然后对于一个节点k,m.lower_bound(k)->second就是这个val。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAX=3e5+100,INF=0x7fffffff;
      4 struct ppp{
      5     int ch[2],rnd,size,l,r,fa;
      6 }treap[MAX];
      7 map<int,int> f;
      8 int n,m,a,tot,root,lnow=INF,cnt=0;
      9  void update(int p)
     10 {
     11     treap[p].size=treap[treap[p].ch[0]].size+treap[treap[p].ch[1]].size+treap[p].r-treap[p].l+1;
     12     treap[treap[p].ch[0]].fa=treap[treap[p].ch[1]].fa=p;
     13     treap[0]=(ppp){0,0,0,0,0,0,0};
     14 }
     15  int divide(int now,int k)//now保留前k个 
     16 {
     17     if(k==treap[now].r-treap[now].l+1)    return 0;
     18     if(k==0)    return now; 
     19     tot++;
     20     treap[tot]=(ppp){0,0,rand(),0,treap[now].l+k,treap[now].r,0};
     21     
     22     f[treap[now].r]=tot;
     23     f[treap[now].l+k-1]=now;
     24 
     25     treap[now].r=treap[now].l+k-1;
     26     treap[tot].ch[1]=treap[now].ch[1];
     27     if(treap[now].rnd<treap[tot].rnd)//tot防在右下角 
     28     {
     29         treap[now].ch[1]=tot;
     30         update(tot);
     31         update(now);
     32     }
     33     else
     34     {
     35         treap[now].ch[1]=0;
     36         treap[tot].ch[0]=now;
     37         treap[tot].fa=treap[now].fa;
     38         treap[treap[now].fa].ch[treap[treap[now].fa].ch[1]==now?1:0]=tot;
     39         update(now);
     40         update(tot);
     41         update(treap[tot].fa);
     42     }
     43     if(treap[tot].fa==0)    root=tot;
     44     return tot;
     45 }
     46  int merge(int x,int y)
     47 {
     48     if(x==0 or y==0)
     49         return x+y;
     50     if(treap[x].rnd>treap[y].rnd)
     51     {
     52         treap[y].ch[0]=merge(x,treap[y].ch[0]);
     53         update(y);
     54         return y;
     55     }
     56     else
     57     {
     58         treap[x].ch[1]=merge(treap[x].ch[1],y);
     59         update(x);
     60         return x;
     61     }
     62 }
     63  void split(int now,int &x,int &y,int rank)
     64 {   
     65     if(rank==0)
     66     {
     67         treap[now].fa=treap[y].fa;
     68         x=0,y=now;
     69         return ;
     70     }
     71     if(rank>=treap[now].size)
     72     {
     73         treap[now].fa=treap[x].fa;
     74         x=now,y=0;
     75         return ;
     76     }
     77     if(treap[treap[now].ch[0]].size>=rank)
     78     {
     79         treap[now].fa=treap[y].fa;
     80         y=now;
     81         split(treap[now].ch[0],x,treap[now].ch[0],rank);
     82         update(now);
     83     }
     84     else if(treap[treap[now].ch[0]].size+treap[now].r-treap[now].l+1<=rank)
     85     {
     86         treap[now].fa=treap[x].fa;
     87         x=now;
     88         split(treap[now].ch[1],treap[now].ch[1],y,rank-(treap[treap[now].ch[0]].size+treap[now].r-treap[now].l+1));
     89         update(now);
     90     }
     91     else
     92     {
     93         int ori_fa=treap[now].fa; 
     94         int k=divide(now,rank-treap[treap[now].ch[0]].size-1);
     95         int q=divide(k,1);
     96         while(treap[now].fa!=ori_fa)
     97             now=treap[now].fa;
     98         split(now,x,y,rank);
     99     }
    100 }
    101  void init()
    102 {
    103     root=++tot;
    104     treap[root]=(ppp){0,0,rand(),n,1,n,0};
    105     f[n]=root;
    106 }
    107  int find(int p)
    108 {
    109     int fa=treap[p].fa;
    110     if(fa==0 or p==0 or p==fa)    return 0;
    111     int son=treap[fa].ch[1]==p;
    112     if(son)    return treap[treap[fa].ch[0]].size+treap[fa].r-treap[fa].l+1+find(fa);
    113     else    return find(fa);
    114 }
    115  int getrank(int x)
    116 {
    117     map<int,int>::iterator it=f.lower_bound(x);
    118     int p=it->second;
    119     return find(p)+treap[treap[p].ch[0]].size+x-treap[p].l+1;
    120 }
    121 int main()
    122 {
    123     scanf("%d%d",&n,&m);
    124     init();
    125     for(int i=1;i<=m;i++)
    126     {
    127         int opt,x1,y1;
    128         scanf("%d%d",&opt,&x1);
    129         x1-=a;
    130         if(opt==1)
    131         {
    132             scanf("%d",&y1);
    133             y1-=a;
    134             int rank=getrank(x1);
    135             printf("%d
    ",rank);
    136             a=rank;
    137             int x=0,y=0,z=0;
    138             split(root,x,y,rank-1);
    139             split(y,z,y,1);
    140             treap[z].l=treap[z].r=y1;
    141             f[y1]=z;
    142             f.erase(x1);
    143             root=merge(merge(x,z),y);
    144         }
    145         else if(opt==2)
    146         {
    147             int rank=getrank(x1);
    148             printf("%d
    ",rank);
    149             a=rank;
    150             int x=0,y=0,z=0;
    151             split(root,x,y,rank-1);
    152             split(y,z,y,1);
    153             root=merge(merge(z,x),y);
    154         }
    155         else if(opt==3)
    156         {
    157             int rank=getrank(x1);
    158             printf("%d
    ",rank);
    159             a=rank;
    160             int x=0,y=0,z=0;
    161             split(root,x,y,rank-1);
    162             split(y,z,y,1);
    163             root=merge(merge(x,y),z);
    164         }
    165         else if(opt==4)
    166         {
    167             int x=0,y=0,z=0;
    168             split(root,x,y,x1-1);
    169             split(y,z,y,1);
    170             a=treap[z].l;
    171             printf("%d
    ",a);
    172             root=merge(merge(x,z),y);
    173         }
    174     }
    175     return 0;
    176 }
    View Code

    四、P3765 总统选举

      此题需要维护一个出现次数>1/2的区间众数,神奇的方法:摩尔比较法。利用线段树维护可能的众数,然后利用平衡树去判断,此众数是否符合要求。

      如果说,是一般的区间众数,貌似只能用分块乱搞。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAX=5e5+2;
      4 struct ppp{
      5     int cnt,cand;
      6 }tree[MAX<<2];
      7 struct iop{
      8     int val,ch[2],size,rnd;
      9 }treap[MAX<<1];
     10 int root[MAX],tot,n,m,pic[MAX],modify[MAX<<1];//pic ÏÈÓÃÓÚ´¢´æԭͼ£¬ºóÓÃÓÚ´æÈ¡Ï߶ÎÊ÷½Úµã±àºÅ 
     11 inline void up(int node)
     12 {
     13     if(tree[node<<1].cand==tree[(node<<1)|1].cand)
     14     {
     15         tree[node].cand=tree[node<<1].cand;
     16         tree[node].cnt=tree[node<<1].cnt+tree[(node<<1)|1].cnt;
     17     }
     18     else
     19     {
     20         if(tree[node<<1].cnt>=tree[(node<<1)|1].cnt) 
     21             tree[node].cnt=tree[node<<1].cnt-tree[(node<<1)|1].cnt,tree[node].cand=tree[node<<1].cand;
     22         else 
     23             tree[node].cnt=tree[(node<<1)|1].cnt-tree[node<<1].cnt,tree[node].cand=tree[(node<<1)|1].cand;
     24     }
     25 }
     26 void build(int node,int l,int r)
     27 {
     28     if(l==r)
     29     {
     30         tree[node].cand=pic[l];
     31         tree[node].cnt=1;
     32         pic[l]=node;
     33         return;
     34     }
     35     else
     36     {
     37         int mid=(l+r)>>1;
     38         build(node<<1,l,mid);
     39         build((node<<1)|1,mid+1,r);
     40         up(node);
     41     }
     42 }
     43 inline ppp find(int node,int l,int r,int L,int R)
     44 {
     45     int mid=(L+R)>>1;
     46     if(l==L and r==R)    return tree[node];
     47     if(r<=mid)
     48         return find(node<<1,l,r,L,mid);
     49     else if(l>mid)
     50         return find((node<<1)|1,l,r,mid+1,R);
     51     else
     52     {
     53         ppp a=find(node<<1,l,mid,L,mid);
     54         ppp b=find((node<<1)|1,mid+1,r,mid+1,R);
     55         ppp c;
     56         if(a.cand==b.cand)    
     57             c.cnt=a.cnt+b.cnt,c.cand=a.cand;
     58         else
     59         {
     60             if(a.cnt>=b.cnt) c.cnt=a.cnt-b.cnt,c.cand=a.cand;
     61             else c.cnt=b.cnt-a.cnt,c.cand=b.cand;
     62         }
     63         return c;
     64     }
     65 }
     66 inline void update(int p)
     67 {
     68     treap[p].size=treap[treap[p].ch[0]].size+treap[treap[p].ch[1]].size+1;
     69 }
     70 inline int NEW(int val)
     71 {
     72     tot++;
     73     treap[tot]=(iop){val,0,0,1,rand()};
     74     return tot;
     75 }
     76 inline int merge(int x,int y)
     77 {
     78     if(x==0 or y==0 )
     79         return x+y;
     80     if(treap[x].rnd<treap[y].rnd)
     81     {
     82         treap[x].ch[1]=merge(treap[x].ch[1],y);
     83         update(x);
     84         return x;
     85     }
     86     else
     87     {
     88         treap[y].ch[0]=merge(x,treap[y].ch[0]);
     89         update(y);
     90         return y;
     91     }
     92 }
     93 inline void split(int now,int &x,int &y,int val)
     94 {
     95     if(now==0)
     96     {
     97         x=0,y=0;
     98         return ;
     99     }
    100     if(treap[now].val<=val)
    101     {
    102         x=now;
    103         split(treap[now].ch[1],treap[now].ch[1],y,val);
    104     }
    105     else
    106     {
    107         y=now;
    108         split(treap[now].ch[0],x,treap[now].ch[0],val);
    109     }
    110     update(now);
    111 }
    112 inline bool check(int l,int r,int cad)
    113 {
    114     if(root[cad]==0)
    115         return false;
    116     int x,y,z;
    117     split(root[cad],x,y,l-1);
    118     split(y,y,z,r); 
    119     bool ans=(treap[y].size<<1)>(r-l+1);
    120     root[cad]=merge(merge(x,y),z);
    121     return ans;
    122 }
    123 inline void change(int voter,int cad)
    124 {
    125     //------------------------------treap
    126     int ori=tree[pic[voter]].cand;
    127     int x,y,z;
    128     split(root[ori],x,y,voter-1);
    129     split(y,y,z,voter);
    130     root[ori]=merge(x,z);
    131     split(root[cad],x,z,voter-1);
    132     root[cad]=merge(merge(x,y),z);
    133     //-----------------------------segment_tree
    134     int node=pic[voter];
    135     tree[node].cand=cad;
    136     node>>=1;
    137     while(node)
    138     {
    139         up(node);
    140         node>>=1;
    141     }
    142 }
    143 int main()
    144 {
    145     scanf("%d%d",&n,&m);
    146     for(int i=1;i<=n;i++)
    147     {
    148         scanf("%d",&pic[i]);
    149         int p=NEW(i);
    150         if(!root[pic[i]])
    151             root[pic[i]]=p;
    152         else
    153             root[pic[i]]=merge(root[pic[i]],p);
    154     }
    155     build(1,1,n);
    156     for(int i=1;i<=m;i++)
    157     {
    158         int l,r,s,k;
    159         scanf("%d%d%d%d",&l,&r,&s,&k);
    160         for(int j=1;j<=k;j++)
    161             scanf("%d",&modify[j]);
    162         int cad=find(1,l,r,1,n).cand;
    163         if(check(l,r,cad))    
    164             s=cad;
    165         for(int j=1;j<=k;j++)
    166             change(modify[j],s);
    167         printf("%d
    ",s);
    168     }
    169     int winner=-1;
    170     for(int i=1;i<=n;i++)
    171         if((treap[root[i]].size<<1)>n)    winner=i;
    172     printf("%d",winner);
    173     return 0;
    174 }
    View Code

     五、咕咕咕。。。。

  • 相关阅读:
    团队项目冲刺七
    团队项目冲刺六
    团队项目冲刺5
    团队项目冲刺4
    团队项目测试计划
    团队项目冲刺第三天进度和遇到问题
    团队项目冲刺第二天进度和问题
    博客园用户体验
    团队项目冲刺第一天进度和问题
    团队项目风险
  • 原文地址:https://www.cnblogs.com/member-re/p/10357721.html
Copyright © 2011-2022 走看看