• ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】


    题目链接:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112

    题意:

    求动态区间第K大。

    分析:

    把修改操作看成删除与增加,对所有操作进行整体二分。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    #define pr(x) cout << #x << ": " << x << "  "
    #define pl(x) cout << #x << ": " << x << endl;
    const int maxn = 50000 + 5, maxq = 20000 + 5, oo = 0x3f3f3f3f;
    int n, m, tot;
    int a[maxn];
    struct Query{
        int x, y, k;
        int id, type;
    }q[maxn + maxq], q1[maxn + maxq], q2[maxn + maxq];
    int bit[maxn];
    int ans[maxq];
    void add(int i, int x)
    {
        while(i <= n){
            bit[i] += x;
            i += i & -i;
        }
    }
    int sum(int i)
    {
        int ans = 0;
        while(i > 0){
            ans += bit[i];
            i -= i & -i;
        }
        return ans;
    }
    void solve(int ql, int qr, int l, int r)
    {
        if(ql > qr) return ;
        if(l == r){
            for(int i = ql; i <= qr; i++){
                if(q[i].type == 2) ans[q[i].id] = l;
            }
            return ;
        }
        int t1 = 0, t2 = 0;
        int mid = l + r >> 1;
       // pl(mid);
        for(int i = ql; i <= qr; i++){
            if(q[i].type == 1){
                if(q[i].x <= mid){
                    add(q[i].id, q[i].y);
                    q1[t1++] = q[i];
                }else q2[t2++] = q[i];
            }else{
                int tmp = sum(q[i].y) -sum(q[i].x - 1);
                if(tmp >= q[i].k) q1[t1++] = q[i];
                else {
                        q[i].k -= tmp;
                        q2[t2++] = q[i];
                }
            }
        }
        for(int i = 0; i < t1; i++){
            if(q1[i].type == 1) add(q1[i].id, -q1[i].y);
        }
        for(int i = 0; i < t1; i++) q[ql + i] = q1[i];
        for(int i = 0; i < t2; i++) q[t1 + i + ql] = q2[i];
    
        solve(ql, ql + t1 - 1, l, mid);
        solve(ql + t1, qr, mid + 1, r);
    }
    int main (void)
    {
        int x;scanf("%d", &x);
        while(x--){
            scanf("%d%d", &n, &m);
            tot = 0;
            memset(bit, 0, sizeof(bit));
            for(int i = 1; i <= n; i++){
                scanf("%d", &a[i]);
                q[++tot] = (Query){a[i], 1, oo, i, 1};
            }
            char s[2];
            int x, y, k;
            int cnt = 0;
            for(int i = 1; i <= m; i++){
                scanf("%s%d%d", s, &x, &y);
                if(s[0] == 'Q'){
                    scanf("%d", &k);
                    q[++tot] = (Query){x, y, k, ++cnt, 2};
                }else{
                    q[++tot] = (Query){a[x], -1, oo, x, 1};
                    q[++tot] = (Query){y, 1, oo, x, 1};
                }
            }
            solve(1, tot, 0, oo);
            for(int i = 1; i <= cnt; i++){
                printf("%d
    ", ans[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    个人所得税避税的10种方法
    营业税
    融资租赁
    会计等式
    公司公积金
    fixed语句
    自由之路
    $or操作符
    $in 操作符
    Redis 字典的实现
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758633.html
Copyright © 2020-2023  润新知