zoj2112 Dynamic Rankings 动态区间第k大,树状数组套平衡树
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n,m; int a[maxn]; char op[5];int L,R,k,p,c; ///---treap struct Node { int ch[2]; int r,v; int sz; };Node tr[maxn];int rt[maxn]; int tot1; int s[maxn],tot2; int newnode() { int o; if(tot2) o=s[tot2--]; else o=++tot1; tr[o].ch[0]=tr[o].ch[1]=-1; tr[o].r=rand();tr[o].v=0; tr[o].sz=1; return o; } void up(int o) { tr[o].sz=1; if(~tr[o].ch[0]) tr[o].sz+=tr[tr[o].ch[0]].sz; if(~tr[o].ch[1]) tr[o].sz+=tr[tr[o].ch[1]].sz; } void rot(int &o,int d) { int k=tr[o].ch[d^1]; tr[o].ch[d^1]=tr[k].ch[d]; tr[k].ch[d]=o; up(o);up(k); o=k; } void Insert(int &o,int x) { if(o==-1){ o=newnode(); tr[o].v=x; return; } int d=x<tr[o].v?0:1; Insert(tr[o].ch[d],x); if(tr[tr[o].ch[d]].r>tr[o].r) rot(o,d^1); up(o); } void Remove(int &o,int x) { if(o==-1) return; if(tr[o].v==x){ if(tr[o].ch[0]==-1) s[++tot2]=o,o=tr[o].ch[1]; else if(tr[o].ch[1]==-1) s[++tot2]=o,o=tr[o].ch[0]; else{ int d=tr[tr[o].ch[0]].r>tr[tr[o].ch[1]].r?0:1; rot(o,d^1); Remove(tr[o].ch[d^1],x); } if(~o) up(o); return; } if(x<tr[o].v) Remove(tr[o].ch[0],x); else Remove(tr[o].ch[1],x); if(~o) up(o); } int getcnt(int &o,int y) { if(o==-1) return 0; if(y<=tr[o].v) return getcnt(tr[o].ch[0],y); int ls=tr[o].ch[0]==-1?0:tr[tr[o].ch[0]].sz; return ls+1+getcnt(tr[o].ch[1],y); } int getcnt2(int &o,int y) { if(o==-1) return 0; if(y<tr[o].v) return getcnt(tr[o].ch[0],y); int ls=tr[o].ch[0]==-1?0:tr[tr[o].ch[0]].sz; return ls+1+getcnt2(tr[o].ch[1],y); } ///---BIT int lowbit(int x) { return x&-x; } void add(int p,int c) { while(p<=n){ Insert(rt[p],c); p+=lowbit(p); } } void del(int p,int c) { while(p<=n){ Remove(rt[p],c); p+=lowbit(p); } } int sum(int p,int y) { int res=0; while(p){ res+=getcnt(rt[p],y); p-=lowbit(p); } return res; } int sum2(int p,int y) { int res=0; while(p){ res+=getcnt2(rt[p],y); p-=lowbit(p); } return res; } int bin(int L,int R,int l,int r,int k) { while(l<=r){ int m=(l+r)>>1; int cnt=sum(R,m)-sum(L-1,m); int cnt2=sum2(R,m)-sum2(L-1,m); if(cnt<=k-1&&cnt2>=k) return m; if(k>cnt2) l=m+1; else r=m-1; } } void Init() { memset(rt,-1,sizeof(rt)); tot1=tot2=0; } int main() { //freopen("in.txt","r",stdin); int T;cin>>T; while(T--){ scanf("%d%d",&n,&m); Init(); REP(i,1,n) scanf("%d",&a[i]); REP(i,1,n) add(i,a[i]); while(m--){ scanf("%s",op); if(op[0]=='C'){ scanf("%d%d",&p,&c); del(p,a[p]); add(p,c); a[p]=c; } else{ scanf("%d%d%d",&L,&R,&k); printf("%d\n",bin(L,R,0,INF,k)); } } } return 0; }
注意下二分要算两个,小于和小于等于的。。。
然后直接树状数组或线段树套上平衡树就可以了。
没有AC不了的题,只有不努力的ACMER!