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 }
  • 相关阅读:
    UVALive 6909 Kevin's Problem 数学排列组合
    UVALive 6908 Electric Bike dp
    UVALive 6907 Body Building tarjan
    UVALive 6906 Cluster Analysis 并查集
    八月微博
    hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形
    hdu 5792 World is Exploding 树状数组
    hdu 5791 Two dp
    hdu 5787 K-wolf Number 数位dp
    hdu 5783 Divide the Sequence 贪心
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6390479.html
Copyright © 2011-2022 走看看