• BZOJ1901 ZOJ2112 线段树+treap (线段树套线段树)


    BZOJ1901:
    线段树套线段树做法:
    (外层线段树 里层动态开节点的权值线段树)
    有一个小小的trick 可以省掉二分变成nlog^2n的
    就是把查询的区间都取出来… logn个一起走…
    2016.2.14Upd

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=10050;
    int root[N*8],n,m,cnt,tot,base[N*2],L[N*200],R[N*200],tree[N*200],a[N],stk[N],top;
    struct Ask{char s[3];int i,j,k;}ask[N];
    void Insert(int l,int r,int &pos,int wei,int f){
        if(!pos)pos=++cnt;tree[pos]+=f;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(mid<wei)Insert(mid+1,r,R[pos],wei,f);
        else Insert(l,mid,L[pos],wei,f);
    }
    void insert(int l,int r,int pos,int num,int wei,int f){
        Insert(1,tot,root[pos],wei,f);
        if(l==r)return;
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<num)insert(mid+1,r,rson,num,wei,f);
        else insert(l,mid,lson,num,wei,f);
    }
    void query(int l,int r,int pos,int L,int R){
        if(l>=L&&r<=R){stk[++top]=root[pos];return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)query(mid+1,r,rson,L,R);
        else if(mid>=R)query(l,mid,lson,L,R);
        else query(l,mid,lson,L,R),query(mid+1,r,rson,L,R);
    }
    int Query(int xx,int yy,int kth){
        top=0,query(1,n,1,xx,yy);
        int l=1,r=tot;
        while(l<r){
            int temp=0;
            for(int i=1;i<=top;i++)temp+=tree[L[stk[i]]];
            if(temp>=kth){
                r=(l+r)>>1;
                for(int i=1;i<=top;i++)stk[i]=L[stk[i]];
            }
            else{
                l=(l+r)/2+1,kth-=temp;
                for(int i=1;i<=top;i++)stk[i]=R[stk[i]];
            }
        }
        printf("%d
    ",base[l]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),base[++tot]=a[i];
        for(int i=1;i<=m;i++){
            scanf("%s%d%d",ask[i].s,&ask[i].i,&ask[i].j);
            if(ask[i].s[0]=='Q')scanf("%d",&ask[i].k);
            else base[++tot]=ask[i].j;
        }
        sort(base+1,base+1+tot);tot=unique(base+1,base+1+tot)-base-1;
        for(int i=1;i<=n;i++)insert(1,n,1,i,lower_bound(base+1,base+1+tot,a[i])-base,1);
        for(int i=1;i<=m;i++){
            if(ask[i].s[0]=='Q')Query(ask[i].i,ask[i].j,ask[i].k);
            else{
                insert(1,n,1,ask[i].i,lower_bound(base+1,base+1+tot,a[ask[i].i])-base,-1);
                insert(1,n,1,ask[i].i,lower_bound(base+1,base+1+tot,ask[i].j)-base,1);
                a[ask[i].i]=ask[i].j;
            }
        }
    }

    线段树+treap

    //By SiriusRen
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define N 600050
    char op[3];
    int n,m,t,root[N],size,a[N],tmp,L,R,xx;
    struct Treap{int ch[2],v,cnt,rnd,sz;}tr[N];
    void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;}
    void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;}
    void insert(int &k,int num){
        if(!k){k=++size;tr[k].cnt=tr[k].sz=1,tr[k].rnd=rand(),tr[k].v=num;return;}
        tr[k].sz++;
        if(tr[k].v==num){tr[k].cnt++;return;}
        bool f=num>tr[k].v;
        insert(tr[k].ch[f],num);
        if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f);
    }
    void Build(int l,int r,int pos){
        insert(root[pos],a[t]);
        if(l==r)return;
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid>=t)Build(l,mid,lson);
        else Build(mid+1,r,rson);
    }
    void query(int k,int num){
        if(!k)return;
        if(tr[k].v==num){tmp+=tr[tr[k].ch[0]].sz;return;}
        else if(tr[k].v>num)query(tr[k].ch[0],num);
        else tmp+=tr[tr[k].ch[0]].sz+tr[k].cnt,query(tr[k].ch[1],num);
    }
    void Query(int l,int r,int pos,int num){
        if(l>=L&&r<=R){query(root[pos],num);return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)Query(mid+1,r,rson,num);
        else if(mid>=R)Query(l,mid,lson,num);
        else Query(l,mid,lson,num),Query(mid+1,r,rson,num);
    }
    void b_srch(){
        int l=0,r=0x3fffffff,Ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            tmp=1,Query(1,n,1,mid);
            if(tmp<=xx)Ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%d
    ",Ans);
    }
    void del(int &k,int num){
        if(tr[k].v==num){
            if(tr[k].cnt>1)tr[k].sz--,tr[k].cnt--;
            else if(tr[k].ch[0]*tr[k].ch[1]==0)k=tr[k].ch[0]+tr[k].ch[1];
            else rot(k,tr[tr[k].ch[0]].rnd>tr[tr[k].ch[1]].rnd),del(k,num);
        }
        else tr[k].sz--,del(tr[k].ch[num>tr[k].v],num);
    }
    void Change(int l,int r,int pos){
        del(root[pos],a[L]),insert(root[pos],xx);
        if(l==r)return;
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)Change(mid+1,r,rson);
        else Change(l,mid,lson);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(t=1;t<=n;t++)
            scanf("%d",&a[t]),Build(1,n,1);
        for(int i=1;i<=m;i++){
            scanf("%s",op);
            if(op[0]=='Q')scanf("%d%d%d",&L,&R,&xx),b_srch();
            else scanf("%d%d",&L,&xx),Change(1,n,1),a[L]=xx;
        }
    }

    加个多case就是ZOJ2112了:

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 1000050
    char op[3];
    int n,m,t,root[50050*8],size,a[50050],tmp,L,R,xx,cases;
    struct Treap{int ch[2],v,cnt,rnd,sz;}tr[N];
    void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;}
    void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;}
    void insert(int &k,int num){
        if(!k){k=++size;tr[k].cnt=tr[k].sz=1,tr[k].rnd=rand(),tr[k].v=num;return;}
        tr[k].sz++;
        if(tr[k].v==num){tr[k].cnt++;return;}
        bool f=num>tr[k].v;
        insert(tr[k].ch[f],num);
        if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f);
    }
    void Build(int l,int r,int pos){
        insert(root[pos],a[t]);
        if(l==r)return;
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid>=t)Build(l,mid,lson);
        else Build(mid+1,r,rson);
    }
    void query(int k,int num){
        if(!k)return;
        if(tr[k].v==num){tmp+=tr[tr[k].ch[0]].sz;return;}
        else if(tr[k].v>num)query(tr[k].ch[0],num);
        else tmp+=tr[tr[k].ch[0]].sz+tr[k].cnt,query(tr[k].ch[1],num);
    }
    void Query(int l,int r,int pos,int num){
        if(l>=L&&r<=R){query(root[pos],num);return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)Query(mid+1,r,rson,num);
        else if(mid>=R)Query(l,mid,lson,num);
        else Query(l,mid,lson,num),Query(mid+1,r,rson,num);
    }
    void b_srch(){
        int l=0,r=0x3fffffff,Ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            tmp=1,Query(1,n,1,mid);
            if(tmp<=xx)Ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%d
    ",Ans);
    }
    void del(int &k,int num){
        if(tr[k].v==num){
            if(tr[k].cnt>1)tr[k].sz--,tr[k].cnt--;
            else if(tr[k].ch[0]*tr[k].ch[1]==0)k=tr[k].ch[0]+tr[k].ch[1];
            else rot(k,tr[tr[k].ch[0]].rnd>tr[tr[k].ch[1]].rnd),del(k,num);
        }
        else tr[k].sz--,del(tr[k].ch[num>tr[k].v],num);
    }
    void Change(int l,int r,int pos){
        del(root[pos],a[L]),insert(root[pos],xx);
        if(l==r)return;
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)Change(mid+1,r,rson);
        else Change(l,mid,lson);
    }
    int main(){
        scanf("%d",&cases);
        while(cases--){
            size=0,memset(root,0,sizeof(root));
            scanf("%d%d",&n,&m);
            for(int i=0;i<=n*20;i++)tr[i].ch[0]=tr[i].ch[1]=tr[i].v=tr[i].sz=tr[i].cnt=0;
            for(t=1;t<=n;t++)
                scanf("%d",&a[t]),Build(1,n,1);
            for(int i=1;i<=m;i++){
                scanf("%s",op);
                if(op[0]=='Q')scanf("%d%d%d",&L,&R,&xx),b_srch();
                else scanf("%d%d",&L,&xx),Change(1,n,1),a[L]=xx;
            }
        }
    }
  • 相关阅读:
    hibernate 数据处理
    oracle函数
    TCP聊天工具
    Hibernate批量处理数据、HQL连接查询
    Hibernate二级缓存配置
    Hibernate一对一关联映射配置
    Hibernate延迟加载
    Hibernate双向多对多关联
    06章 映射一对多双向关联关系、以及cascade、inverse属性
    映射对象标识符
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532158.html
Copyright © 2020-2023  润新知