zoukankan      html  css  js  c++  java
  • 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;  
    }  
  • 相关阅读:
    【Python专题】python入门之代码编辑器和输入输出
    【Python专题】python入门之一:搭建开发环境
    制作你的专属BB8机器人
    《专题:C++语法基础》篇五:循环程序设计
    《专题:C++语法基础》篇四:C++分支程序设计
    《专题:C++语法基础》篇三:C++中的算术运算、赋值运算
    数据库SQL Server2012笔记(八)——Statement与PreparedStatement的区别,JDBC方式操作数据库
    数据库SQL Server2012笔记(七)——java 程序操作sql server
    数据库SQL Server2012笔记(六)——修改表、数据的备份和恢复
    数据库SQL Server2012笔记(三)——表的复杂查询
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6375947.html
Copyright © 2011-2022 走看看