bzoj1901: Zju2112 Dynamic Rankings
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1901
题解:树套树,线段树+treap(sb的我以为有多组数据。。。。。。呃呵呵呵狂RE)
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #define N 200001 #define M 1300001 #define inf 1000000000 using namespace std; int n,m,sz,ans,a[N]; int ls[M],rs[M],rnd[M],v[M],s[M],w[M]; int root[N]; int read() { int x=0; char ch; bool bo=0; while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); if (bo) return -x; return x; } void updata(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];} void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; updata(k); k=t;} void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; updata(k); k=t;} void insert(int &k,int num) { if (!k) {k=++sz; s[k]=w[k]=1; v[k]=num; rnd[k]=rand(); return;} s[k]++; if (v[k]==num) w[k]++; else if (v[k]>num){ insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k);} else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);} } void del(int &k,int num) { if (v[k]==num) { if (w[k]>1) {w[k]--; s[k]--; return;} if (ls[k]*rs[k]==0) k=ls[k]+rs[k]; else if (rnd[ls[k]]<rnd[rs[k]]) {rturn(k); del(k,num);} else {lturn(k); del(k,num);} } else if (v[k]<num) {del(rs[k],num);s[k]--;} else {del(ls[k],num);s[k]--;} } void build(int k,int l,int r,int pos,int val) { insert(root[k],val); int mid=(l+r)>>1; if (l==r) return; if (pos<=mid) build(k*2,l,mid,pos,val); else build(k*2+1,mid+1,r,pos,val); } void change (int k,int l,int r,int pos,int val,int pre) { del(root[k],pre); insert(root[k],val); if (l==r) return; int mid=(l+r)>>1; if (pos<=mid) change(k*2,l,mid,pos,val,pre); else change(k*2+1,mid+1,r,pos,val,pre); } void ask_rank(int k,int num) { if (!k) return; if (num==v[k]) {ans+=s[ls[k]]; return;} else if (v[k]>num){ask_rank(ls[k],num);} else {ans+=s[ls[k]]+w[k]; ask_rank(rs[k],num);} } void query_rank(int k,int l,int r,int x,int y,int num) { if (l==x && y==r){ask_rank(root[k],num); return;} int mid=(l+r)>>1; if (y<=mid) query_rank(k*2,l,mid,x,y,num); else if (mid<x) query_rank(k*2+1,mid+1,r,x,y,num); else { query_rank(k*2,l,mid,x,mid,num); query_rank(k*2+1,mid+1,r,mid+1,y,num); } } void query_k(int x,int y,int num) { int l=0,r=inf,tmp; while (l<r) { int mid=(l+r)>>1; ans=1; query_rank(1,1,n,x,y,mid); if (ans>num) r=mid; else {l=mid+1; tmp=mid;} } printf("%d\n",tmp); } int main() { memset(root,0,sizeof(root)); memset(ls,0,sizeof(ls)); memset(rs,0,sizeof(rs)); memset(s,0,sizeof(s)); memset(w,0,sizeof(w)); sz=0; n=read(); m=read(); for (int i=1; i<=n; i++) a[i]=read(); for (int i=1; i<=n; i++) build(1,1,n,i,a[i]); char ch[10]; int l,r,k,pos,val; for (int i=1; i<=m; i++) { scanf("%s",ch); if (ch[0]=='Q') {l=read(); r=read(); k=read(); ans=1; query_k(l,r,k);} if (ch[0]=='C') {pos=read(); val=read(); change(1,1,n,pos,val,a[pos]); a[pos]=val;} } }
我太蒟蒻了,所以神犇们留下意见让我跪膜