COGS TYVJ1730 二逼平衡树

位置树状数组套权值线段树,传说中的动态主席树

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 50010
  4 #define M 20000010
  5 #define mid ((l+r)>>1)
  6 #define rep(a,b,c) for(register int (a)=(b);(a)<=(c);++(a))
  7 #define RG register
  8 #define IL inline
  9 #define mst(a,b) memset((a),(b),sizeof((a))) 
 10 #define lowbit(p) ((p)&-(p))
 11 IL bool isitdigit(char c){    return c<='9'&&c>='0';    }
 12 IL int read()
 13 {
 14     RG int s,f=1;RG char c;
 15     while(!isitdigit(c=getchar())) (c=='-')&&(f=-1);
 16     for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0');
 17     return s*f;
 18 }
 19 
 20 int a[N],ls[M],rs[M],v[M],tot,root[N],n,m;
 21 void addit(int p,int d,int& o,int l=0,int r=1e8)
 22 {
 23     if(!o) o=++tot;
 24     v[o]+=d;
 25     if(l==r) return;
 26     if(p<=mid) addit(p,d,ls[o],l,mid);
 27     else addit(p,d,rs[o],mid+1,r);
 28     v[o]=v[ls[o]]+v[rs[o]];
 29 }
 30 void add(int p,int x,int d){    for(;p<=n;p+=lowbit(p)) addit(x,d,root[p]);    }
 31 int queryit(int x,int y,int & o,int l=0,int r=1e8)
 32 {
 33     if(!o) return 0;
 34     if(x<=l&&r<=y) return v[o];
 35     int ans=0;
 36     if(x<=mid) ans+=queryit(x,y,ls[o],l,mid);
 37     if(mid<y)ans+=queryit(x,y,rs[o],mid+1,r);
 38     return ans;
 39 }
 40 int query(int l,int r,int x)
 41 {
 42     int ans=0;
 43     for(RG int p=r;p;p-=lowbit(p)) ans+=queryit(0,x-1,root[p]);
 44     for(RG int p=l-1;p;p-=lowbit(p)) ans-=queryit(0,x-1,root[p]);
 45     return ans+1;
 46 }    
 47 int x[N],cx,y[N],cy;
 48 int rank(int s,int e,int k)
 49 {
 50     mst(x,0),mst(y,0),cx=cy=0;
 51     for(RG int p=e;p;p-=lowbit(p)) y[++cy]=root[p];
 52     for(RG int p=s-1;p;p-=lowbit(p)) x[++cx]=root[p];
 53     RG int l=0,r=1e8;
 54     while(l<r)
 55     {
 56         RG int val=0;
 57         rep(i,1,cy) val+=v[ls[y[i]]];
 58         rep(i,1,cx) val-=v[ls[x[i]]];
 59         if(k<=val)
 60         {
 61             r=mid;
 62             rep(i,1,cy) y[i]=ls[y[i]];
 63             rep(i,1,cx) x[i]=ls[x[i]];
 64         }
 65         else{
 66             k-=val,l=mid+1;
 67             rep(i,1,cy) y[i]=rs[y[i]];
 68             rep(i,1,cx) x[i]=rs[x[i]];
 69         }
 70     }
 71     return l;
 72 }
 73 int pre(int l,int r,int k)
 74 {
 75     return rank(l,r,query(l,r,k)-1);
 76 }
 77 int suf(int l,int r,int k)
 78 {
 79     return rank(l,r,query(l,r,k+1));
 80 }
 81 
 82 
 83 int main()
 84 {
 85     freopen("psh.in","r",stdin);
 86     freopen("psh.out","w",stdout);
 87     n=read(),m=read();
 88     rep(i,1,n) a[i]=read(),add(i,a[i],1);
 89     while(m--)
 90     {
 91         RG int ope=read(),l,r,k;
 92         switch(ope)
 93         {
 94             case 1:l=read(),r=read(),k=read(),printf("%d\n",query(l,r,k));break; 
 95             case 2:l=read(),r=read(),k=read(),printf("%d\n",rank(l,r,k));break;
 96             case 3:l=read(),k=read(),add(l,a[l],-1),a[l]=k,add(l,a[l],1);break;
 97             case 4:l=read(),r=read(),k=read(),printf("%d\n",pre(l,r,k));break;
 98             case 5:l=read(),r=read(),k=read(),printf("%d\n",suf(l,r,k));break;
 99         }
100     }
101     
102 }

 

posted @ 2018-07-03 11:02  咸鱼炒蒟蒻  阅读(143)  评论(0编辑  收藏  举报