zoukankan      html  css  js  c++  java
  • bzoj 3065 带插入区间k小值

    替罪羊树套权值线段树。

    计数式垃圾回收。

    复杂度nlog2^n。

    写了半个冬令营。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<vector>
      5 #include<algorithm>
      6 #define N 10000005
      7 #define alpha 0.75
      8 using namespace std;
      9 inline int read()
     10 {
     11     int x=0;char c=getchar();
     12     while(c<'0'||c>'9')c=getchar();
     13     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
     14     return x;
     15 }
     16 int n;
     17 int v[70005],dfn[70005],root[70005],ch[70005][2],size[70005],num,zhi[70005],fa[70005];
     18 int laji[N*2],sz;
     19 struct node
     20 {
     21     int l,r,sum;
     22 }a[N*2];int cnt;
     23 int lv[N*2];
     24 int newnode()
     25 {
     26     if(!sz)
     27     {
     28         cnt++;
     29         lv[cnt]=1;
     30         return cnt;
     31     }
     32     int y=laji[sz--];lv[y]=1;
     33     return y;
     34 }
     35 void shan(int x)
     36 {
     37     if(!x)return;
     38     lv[x]--;
     39     if(!lv[x])
     40     {
     41         shan(a[x].l);shan(a[x].r);
     42         a[x].l=a[x].r=0;a[x].sum=0;
     43         laji[++sz]=x;
     44     }return ;
     45 }
     46 void del(int x,int y,int l,int r,int z)
     47 {
     48     if(l==r)
     49     {
     50         a[x].sum=a[y].sum-1;
     51         return ;
     52     }
     53     int mid=(l+r)>>1;
     54     if(z<=mid)
     55     {
     56         a[x].l=newnode();
     57         del(a[x].l,a[y].l,l,mid,z);
     58         a[x].r=a[y].r;
     59         lv[a[y].r]++;
     60     }
     61     else
     62     {
     63         a[x].r=newnode();
     64         del(a[x].r,a[y].r,mid+1,r,z);
     65         a[x].l=a[y].l;
     66         lv[a[y].l]++;
     67     }
     68     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
     69 }
     70 void insert(int x,int y,int l,int r,int z)
     71 {
     72     if(l==r)
     73     {
     74         a[x].sum=a[y].sum+1;
     75         return ;
     76     }
     77     int mid=(l+r)>>1;
     78     if(z<=mid)
     79     {
     80         a[x].l=newnode();
     81         insert(a[x].l,a[y].l,l,mid,z);
     82         a[x].r=a[y].r;
     83         lv[a[y].r]++;
     84     }
     85     else
     86     {
     87         a[x].r=newnode();
     88         insert(a[x].r,a[y].r,mid+1,r,z);
     89         a[x].l=a[y].l;
     90        lv[a[y].l]++;
     91     }
     92     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
     93 }
     94   
     95 void merge(int x,int y,int z,int l,int r)
     96 {
     97     if(l==r)
     98     {
     99         a[x].sum=a[y].sum+a[z].sum;
    100         return ;
    101     }
    102     int mid=(l+r)>>1;
    103     if(!a[z].l)
    104     {
    105         if(a[y].l)a[x].l=a[y].l,lv[a[y].l]++;
    106     }
    107     else if(!a[y].l)
    108     {
    109         if(a[z].l)a[x].l=a[z].l,lv[a[z].l]++;
    110     }
    111     else
    112     {
    113         a[x].l=newnode();
    114         merge(a[x].l,a[y].l,a[z].l,l,mid);
    115     }
    116     if(!a[z].r)
    117     {
    118         if(a[y].r)a[x].r=a[y].r,lv[a[y].r]++;
    119     }
    120     else if(!a[y].r)
    121     {
    122         if(a[z].r)a[x].r=a[z].r,lv[a[z].r]++;
    123     }
    124     else
    125     {
    126         a[x].r=newnode();
    127         merge(a[x].r,a[y].r,a[z].r,mid+1,r);
    128     }
    129     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    130 }
    131 void push_up(int x)
    132 {
    133     size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
    134     return ;
    135 }
    136 int nw,zi[70005];
    137 void build(int x,int l,int r)
    138 {
    139     size[x]=1;int mid=(l+r)>>1;zhi[x]=zi[mid];
    140     if(l==r)
    141     {
    142         if(!root[x])root[x]=newnode();
    143         insert(root[x],0,0,70000,zhi[x]);
    144         return ;
    145     }
    146     if(l!=mid)
    147     {
    148         ch[x][0]=dfn[++nw];
    149         build(ch[x][0],l,mid-1);
    150     }
    151     ch[x][1]=dfn[++nw];
    152     build(ch[x][1],mid+1,r);
    153     if(!root[x])root[x]=newnode();
    154     merge(root[x],root[ch[x][0]],root[ch[x][1]],0,70000);
    155     int tmp=root[x];
    156     root[x]=newnode();
    157     insert(root[x],tmp,0,70000,zhi[x]);
    158     shan(tmp);
    159     push_up(x);fa[ch[x][0]]=x;fa[ch[x][1]]=x;
    160 }
    161 int rt,bd;
    162 void insert(int k,int x,int y)
    163 {
    164     int tmp=root[k];root[k]=newnode();
    165     insert(root[k],tmp,0,70000,zhi[y]);
    166     shan(tmp);
    167     int l=ch[k][0];
    168     if(size[l]+1>=x)
    169     {
    170         if(!ch[k][0])
    171         {
    172             ch[k][0]=y;
    173             fa[y]=k;push_up(k);
    174             return ;
    175         }
    176         else insert(ch[k][0],x,y);
    177     }
    178     else
    179     {
    180         if(!ch[k][1])
    181         {
    182             ch[k][1]=y;
    183             fa[y]=k;push_up(k);
    184             return ;
    185         }
    186         else insert(ch[k][1],x-size[l]-1,y);
    187     }
    188     push_up(k);
    189     if(max(size[ch[k][0]],size[ch[k][1]])>alpha*size[k])bd=k;
    190 }
    191 int dian[70005],top;
    192 void dfs(int x)
    193 {
    194     if(!x)return ;
    195     dfs(ch[x][0]);
    196     dian[++top]=x;
    197     zi[top]=zhi[x];
    198     shan(root[x]);root[x]=0;
    199     dfs(ch[x][1]);
    200     ch[x][0]=ch[x][1]=0;
    201     fa[x]=0;size[x]=0;
    202     zhi[x]=0;
    203     return ;
    204 }
    205 void rebuild(int k)
    206 {
    207     top=0;int yy=fa[k];
    208     dfs(k);
    209     for(int i=1;i<=top;i++)dfn[i]=dian[i];
    210     nw=0;
    211     int tmp=dfn[++nw];
    212     build(tmp,1,top);
    213     if(yy)
    214     {
    215         if(ch[yy][0]==k)ch[yy][0]=tmp;
    216         else ch[yy][1]=tmp;
    217     }
    218       
    219 }
    220 int tt;
    221 void gai(int x,int t1,int t2)
    222 {
    223     int l=ch[x][0];
    224     int tmp=root[x];root[x]=newnode();
    225     insert(root[x],tmp,0,70000,t2);
    226     shan(tmp);
    227     if(size[l]+1==t1)
    228     {
    229         tt=zhi[x];
    230         tmp=root[x];root[x]=newnode();
    231         del(root[x],tmp,0,70000,tt);
    232         zhi[x]=t2;
    233         return ;    
    234     }
    235     if(size[l]+1>t1)gai(l,t1,t2);
    236     else gai(ch[x][1],t1-size[l]-1,t2);
    237     tmp=root[x];root[x]=newnode();
    238     del(root[x],tmp,0,70000,tt);
    239     shan(tmp);
    240 }
    241 vector<int>t,q;
    242 void query(int x,int l,int r)
    243 {
    244     int L=size[ch[x][0]];
    245     if(l==1&&size[x]==r)
    246     {
    247         t.push_back(root[x]);return ;
    248     }
    249     if(l<=L+1&&r>=L+1)q.push_back(zhi[x]);
    250     if(r<=L)
    251     {
    252         query(ch[x][0],l,r);
    253     }
    254     else if(l>L+1)
    255     {
    256         query(ch[x][1],l-L-1,r-L-1);
    257     }
    258     else
    259     {
    260         if(l<=L)query(ch[x][0],l,L);
    261         if(r>L+1)query(ch[x][1],1,r-L-1);
    262     }
    263 }
    264 int qur(int L,int R,int xx)
    265 {
    266     query(rt,L,R);
    267     int l=0,r=70000,s1=t.size(),s2=q.size();
    268     while(l<r)
    269     { 
    270         int mid=(l+r)>>1;int sum=0;
    271         for(int i=0;i<s1;i++)sum+=a[a[t[i]].l].sum;
    272         for(int i=0;i<s2;i++)
    273         {
    274             if(q[i]>=l&&q[i]<=mid)sum++;
    275         }
    276         if(xx<=sum)
    277         {
    278             for(int i=0;i<s1;i++)t[i]=a[t[i]].l;
    279             r=mid;
    280         }
    281         else
    282         {
    283             xx-=sum;
    284             for(int i=0;i<s1;i++)t[i]=a[t[i]].r;
    285             l=mid+1;
    286         }
    287     }
    288     t.clear();q.clear();
    289     return l;
    290 }
    291 int main()
    292 {
    293     n=read();
    294     for(int i=1;i<=n;i++)zi[i]=read(),dfn[i]=i;
    295     num=n;rt=1;nw=1;
    296     build(1,1,n);
    297     int q;
    298     scanf("%d",&q);
    299     char s[5];
    300     int ans=0;int t1,t2,t3;
    301     for(int i=1;i<=q;i++)
    302     {
    303         if(cnt>19000000)return 0;
    304         scanf("%s",s);
    305         if(s[0]=='M')
    306         {
    307             t1=read();t2=read();
    308             t1^=ans;t2^=ans;
    309             gai(rt,t1,t2);
    310         }
    311         else if(s[0]=='Q')
    312         {
    313             t1=read();t2=read();t3=read();
    314             t1^=ans;t2^=ans;t3^=ans;
    315             ans=qur(t1,t2,t3);
    316             printf("%d
    ",ans);
    317         }
    318         else
    319         {
    320             t1=read();t2=read();
    321             t1^=ans;t2^=ans;
    322             num++;root[num]=newnode();zhi[num]=t2;
    323             size[num]=1;insert(root[num],0,0,70000,t2);
    324             bd=0;
    325             insert(rt,t1,num);
    326             if(bd)rebuild(bd);
    327         }
    328     }
    329     return 0;
    330 }
  • 相关阅读:
    数据结构与算法之美学习笔记:第十七讲
    数据结构与算法之美学习笔记:第二十三讲
    数据结构与算法之美学习笔记:第二十四讲
    数据结构与算法之美学习笔记:第十一讲
    数据结构与算法之美学习笔记:第十讲
    数据结构与算法之美学习笔记:第九讲
    数据结构与算法之美学习笔记:第八讲
    深挖计算机基础:数据结构与算法之美学习笔记
    深挖计算机基础:趣谈Linux操作系统学习笔记
    深挖计算机基础:Linux性能优化学习笔记
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6390479.html
Copyright © 2011-2022 走看看