1901: Zju2112 Dynamic Rankings

来源:互联网 发布:部队网络保密红线讨论 编辑:程序博客网 时间:2024/04/27 14:09

树状数组套主席树,用于解决支持修改的区间k大问题。

由于主席树是一种前缀和,可以用树状数组将修改从n^2*loginf优化到n*logn*loginf。

板子题没有太多解释,直接挂代码。

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cstdlib>#include<cmath>using namespace std;#define rep(i,j,k) for(i=j;i<=k;++i)#define per(i,j,k) for(i=j;i>=k;--i)#define ll long long#define db double#define ldb long double#define pli pair<ll,int>#define mkp make_pair#define X first#define Y secondconst int N=50005,inf=1000000000;struct TREE{int lc,rc,sum;}T[2000000];int n,a[N],rt[N],numl[N],lnl,numr[N],lnr,tot;void add(int x,int y,int l,int r,int &num){if(!num)num=++tot;T[num].sum+=y;if(l==r)return;int mid=l+r>>1;if(x>mid)add(x,y,mid+1,r,T[num].rc);else add(x,y,l,mid,T[num].lc);}int kth(int k,int l,int r){if(l==r)return l;int i,S=0;rep(i,1,lnr)S+=T[T[numr[i]].lc].sum;rep(i,1,lnl)S-=T[T[numl[i]].lc].sum;if(k>S){rep(i,1,lnr)numr[i]=T[numr[i]].rc;rep(i,1,lnl)numl[i]=T[numl[i]].rc;return kth(k-S,l+r+2>>1,r);}rep(i,1,lnr)numr[i]=T[numr[i]].lc;rep(i,1,lnl)numl[i]=T[numl[i]].lc;return kth(k,l,l+r>>1);}int main(){int Q,i,z,x,y,k;char str[2];scanf("%d%d",&n,&Q);rep(i,1,n){scanf("%d",&a[i]);for(z=i;z<=n;z+=z&-z)add(a[i],1,0,inf,rt[z]);}while(Q--){scanf("%s%d%d",str,&x,&y);if(str[0]=='C'){for(z=x;z<=n;z+=z&-z){add(a[x],-1,0,inf,rt[z]);add(y,1,0,inf,rt[z]);}a[x]=y;}else{scanf("%d",&k);for(lnl=0,z=x-1;z;z-=z&-z)numl[++lnl]=rt[z];for(lnr=0,z=y;z;z-=z&-z)numr[++lnr]=rt[z];printf("%d\n",kth(k,0,inf));}}return 0;}


1 0
原创粉丝点击