数据结构--树状数组套主席树(动态区间k小)

来源:互联网 发布:苏州优才通网络怎么样 编辑:程序博客网 时间:2024/05/18 01:20

给大家一波福利,我在洛谷上放了一道bzoj权限题
传送门
都不要说,要不我会被打。。。
有人说的话,我就删了这题了。。
然后就是这个题就是个模板题,直接板子。
我的封装过了,看一看细节,直接用就好了。
代码:

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<cstdlib>#define ll long longusing namespace std;inline int read(){    int x=0;char ch=' ';int f=1;    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();    if(ch=='-')f=-1,ch=getchar();    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();    return x*f;}const int N=1e4+5;const int M=N*300;struct node{    int ls,rs,size;}t[M];int n,m,cnt,tot;int a[N],b[N<<1];inline int Hash(int x){    return lower_bound(b+1,b+cnt+1,x)-b;}struct Q{    int opt,A,B,K;}q[N];struct bit_seg{    int add[30],mns[30],cnt1,cnt2;    int root[N];    inline int lowbit(int x){        return x&-x;    }    inline void insert(int num,int &now,int l,int r,int val){        t[++tot]=t[now];        now=tot;        t[now].size+=val;        if(l==r)return;        int mid=(l+r)>>1;        if(num<=mid)insert(num,t[now].ls,l,mid,val);        else insert(num,t[now].rs,mid+1,r,val);    }    inline int query(int l,int r,int k){        if(l==r)return b[l];        int lsize=0;        for(int i=1;i<=cnt1;i++)lsize+=t[t[add[i]].ls].size;        for(int i=1;i<=cnt2;i++)lsize-=t[t[mns[i]].ls].size;        int mid=(l+r)>>1;        if(k<=lsize){            for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].ls;            for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].ls;            return query(l,mid,k);        }        else{            for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].rs;            for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].rs;            return query(mid+1,r,k-lsize);        }    }    inline void build(){        for(int i=1;i<=n;i++){            a[i]=Hash(a[i]);            for(int j=i;j<=n;j+=lowbit(j)){                insert(a[i],root[j],1,cnt,1);            }        }    }    inline int Query(int l,int r,int k){        cnt1=cnt2=0;        for(int i=l-1;i;i-=lowbit(i))mns[++cnt2]=root[i];        for(int i=r;i;i-=lowbit(i))add[++cnt1]=root[i];        return query(1,cnt,k);    }    inline void Insert(int pos,int x){        for(int i=pos;i<=n;i+=lowbit(i)){            insert(a[pos],root[i],1,cnt,-1);        }        a[pos]=Hash(x);        for(int i=pos;i<=n;i+=lowbit(i)){            insert(a[pos],root[i],1,cnt,1);        }    }}tree;int main(){    n=read();m=read();    for(int i=1;i<=n;i++){        a[i]=read();b[++cnt]=a[i];    }    for(int i=1;i<=m;i++){        char ch[3];        scanf("%s",ch);        if(ch[0]=='Q'){            q[i].opt=0;q[i].A=read();q[i].B=read();q[i].K=read();        }        else{            q[i].opt=1;q[i].A=read();q[i].B=read();b[++cnt]=q[i].B;        }    }    sort(b+1,b+cnt+1);    cnt=unique(b+1,b+cnt+1)-b-1;    tree.build();    for(int i=1;i<=m;i++){        if(q[i].opt){            tree.Insert(q[i].A,q[i].B);        }        else{            printf("%d\n",tree.Query(q[i].A,q[i].B,q[i].K));        }    }    return 0;}
阅读全文
0 0
原创粉丝点击