位置树状数组套权值线段树,传说中的动态主席树
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 }