bzoj1901: Zju2112 Dynamic Rankings

来源:互联网 发布:炒黄金的软件 编辑:程序博客网 时间:2024/05/07 11:08
传送门: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 1000000000using 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;}        }    }
View Code

 

0 0