zoukankan      html  css  js  c++  java
  • ZOJ2112 Dynamic Rank(可持久化线段树套树状数组)

    人生第一道树套树的题,看着bin巨的代码才学会,太累了,文字明天补

    #include<bits/stdc++.h>
    
    using namespace std;
    const int maxn=60010;
    int n,q,m,tot;
    int a[maxn];
    int t[maxn];
    int T[maxn];
    int lson[maxn*40];
    int rson[maxn*40];
    int c[maxn*40];
    int S[maxn];
    
    struct Query {
        int Kind;
        int l,r,k;
    }query[maxn];
    
    void Init_hash (int k) {
        sort(t,t+k);
        m=unique(t,t+k)-t;
    }
    int Hash (int x) {
        return lower_bound(t,t+m,x)-t;
    }
    int build (int l,int r) {
        int root=tot++;
        c[root]=0;
        if (l!=r) {
            int mid=(l+r)>>1;
            lson[root]=build(l,mid);
            rson[root]=build(mid+1,r);
        }
        return root;
    }
    
    int Insert (int root,int pos,int val) {
        int newRoot=tot++;
        int tmp=newRoot;
        int l=0;
        int r=m-1;
        c[newRoot]=c[root]+val;
        while (l<r) {
            int mid=(l+r)>>1;
            if (pos<=mid) {
                lson[newRoot]=tot++;
                rson[newRoot]=rson[root];
                newRoot=lson[newRoot];
                root=lson[root];
                r=mid;
            }
            else {
                rson[newRoot]=tot++;
                lson[newRoot]=lson[root];
                newRoot=rson[newRoot];
                root=rson[root];
                l=mid+1;
            }
            c[newRoot]=c[root]+val;
        }
        return tmp;
    }
    
    
    
    
    //树状数组部分
    int lowbit (int x) {
        return x&-x;
    }
    int bit[maxn];
    void add (int x,int pos,int val) {
        for (int i=x;i<=n;i+=lowbit(i)) S[i]=Insert(S[i],pos,val);
    }
    int getsum (int x) {
        int ans=0;
        for (int i=x;i;i-=lowbit(i)) ans+=c[lson[bit[i]]];
        return ans;
    }
    
    int Query (int left,int right,int k) {
        int left_root=T[left-1];
        int right_root=T[right];
        int l=0;
        int r=m-1;
        for (int i=left-1;i;i-=lowbit(i)) bit[i]=S[i];
        for (int i=right;i;i-=lowbit(i)) bit[i]=S[i];
        while (l<r) {
            int mid=(l+r)>>1;
            int tmp=getsum(right)-getsum(left-1)+c[lson[right_root]]-c[lson[left_root]];
            if (tmp>=k) {
                r=mid;
                for (int i=left-1;i;i-=lowbit(i)) bit[i]=lson[bit[i]];
                for (int i=right;i;i-=lowbit(i)) bit[i]=lson[bit[i]];
                left_root=lson[left_root];
                right_root=lson[right_root];
            }
            else {
                l=mid+1;
                k-=tmp;
                for (int i=left-1;i;i-=lowbit(i)) bit[i]=rson[bit[i]];
                for (int i=right;i;i-=lowbit(i)) bit[i]=rson[bit[i]];
                left_root=rson[left_root];
                right_root=rson[right_root];
            }
        }
        return l;
    }
    
    void Modify (int x,int p,int d) {
        for (int i=x;i<=n;i+=lowbit(i)) {
            S[i]=Insert(S[i],p,d);
        }
    }
    
    
    int main () {
        int tt;
        scanf("%d",&tt);
        while (tt--) {
            scanf("%d%d",&n,&q);
            tot=0;
            m=0;
            for (int i=1;i<=n;i++) {
                scanf("%d",&a[i]);
                t[m++]=a[i];
            }
            char op[10];
            for (int i=0;i<q;i++) {
                scanf("%s",op);
                if (op[0]=='Q') {
                    query[i].Kind=0;
                    scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k);
                }
                else {
                    query[i].Kind=1;
                    scanf("%d%d",&query[i].l,&query[i].r);
                    t[m++]=query[i].r;
                }
            }
            Init_hash(m);
            T[0]=build(0,m-1);
            for (int i=1;i<=n;i++)
                T[i]=Insert(T[i-1],Hash(a[i]),1);
            for (int i=1;i<=n;i++) S[i]=T[0];
            for (int i=0;i<q;i++) {
                if (query[i].Kind==0) {
                    printf("%d
    ",t[Query(query[i].l,query[i].r,query[i].k)]);
                }
                else {
                    Modify(query[i].l,Hash(a[query[i].l]),-1);
                    Modify(query[i].l,Hash(query[i].r),1);
                    a[query[i].l]=query[i].r;
                }
            }
        }
    }
  • 相关阅读:
    微信报错 config:fail.Error:invalid signature
    js动态添加onload、onresize、onscroll事件(另类方法)
    Jquery 读取表单选中值
    Jquery事件
    Jquery
    PHP-query 的用法
    php-数据库访问--数据修改
    php-数据库访问--增、删、改
    php-访问数据库
    php-设计模式
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12902890.html
Copyright © 2011-2022 走看看