• ZOJ 2112 Dynamic Rankings (动态第 K 大)(树状数组套主席树)


    Dynamic Rankings

    Time Limit: 10 Seconds      Memory Limit: 32768 KB

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.

    Your task is to write a program for this computer, which

    - Reads N numbers from the input (1 <= N <= 50,000)

    - Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.


    Input

    The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.


    The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

    Q i j k or
    C i t

    It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

    There're NO breakline between two continuous test cases.


    Output

    For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])

    There're NO breakline between two continuous test cases.


    Sample Input

    2
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3


    Sample Output

    3
    6
    3
    6

     表示不是很懂,先插个眼。。

    #include<cstdio>  
    #include<cstring>  
    #include<cmath>  
    #include<cstdlib>  
    #include<iostream>  
    #include<algorithm>  
    #include<vector>  
    #include<map>  
    #include<queue>  
    #include<stack>  
    #include<string>  
    #include<map>  
    #include<set>  
    #include<ctime>  
    #define eps 1e-6  
    #define LL long long  
    #define pii (pair<int, int>)  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")  
    using namespace std;  
      
    //zoj 2104 动态主席树修改+静态主席树   
    const int maxn = 60000+1000;  
    const int M = 2400000;  
    int n, q, m, tot;  
    int a[maxn], t[maxn];  
    int T[maxn], lson[M], rson[M], c[M];  
    int S[maxn];  
    struct Query {  
        int kind;  
        int l, r, k;  
    } query[10010];  
      
    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++, tmp = newroot;  
        int l = 0, 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 use[maxn];  
    void add(int x, int pos, int d) {  
        while(x <= n) {  
            S[x] = Insert(S[x], pos, d);  
            x += lowbit(x);  
        }  
    }  
    int Sum(int x) {  
        int ret = 0;  
        while(x > 0) {  
            ret += c[lson[use[x]]];  
            x -= lowbit(x);  
        }  
        return ret;  
    }  
    int Query(int left, int right, int k) {  
        int left_root = T[left-1], right_root = T[right];  
        int l = 0, r = m-1;  
        for(int i = left-1; i; i -= lowbit(i)) use[i] = S[i];  
        for(int i = right; i; i -= lowbit(i)) use[i] = S[i];  
        while(l < r) {  
            int mid = (l+r) >> 1;  
            int tmp = Sum(right) - Sum(left-1) + c[lson[right_root]] - c[lson[left_root]];  
            if(tmp >= k) {  
                r = mid;  
                for(int i = left-1; i; i -= lowbit(i)) use[i] = lson[use[i]];  
                for(int i = right; i; i -= lowbit(i)) use[i] = lson[use[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)) use[i] = rson[use[i]];  
                for(int i = right; i; i -= lowbit(i)) use[i] = rson[use[i]];  
                left_root = rson[left_root];  
                right_root = rson[right_root];  
            }         
        }  
        return l;  
    }  
      
    int main() {  
        //freopen("input.txt", "r", stdin);  
        int Tcase; cin >> Tcase;   
        while(Tcase--) {  
            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 {  
                    add(query[i].l, Hash(a[query[i].l]), -1);  
                    add(query[i].l, Hash(query[i].r), 1);  
                    a[query[i].l] = query[i].r;  
                }  
            }         
        }  
        return 0;  
    }  
  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6375947.html
Copyright © 2020-2023  润新知