zoukankan      html  css  js  c++  java
  • [BZOJ3110][Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询

    Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 9354  Solved: 2762 [Submit][Status][Discuss]

    Description

    有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    Input

    第一行N,M 接下来M行,每行形如1 a b c或2 a b c

    Output

    输出每个询问的结果

    Sample Input

    2 5
    1 1 2 1
    1 1 2 2
    2 1 1 2
    2 1 1 1
    2 1 2 3

    Sample Output

    1
    2
    1

    HINT

    【样例说明】
    第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1
    的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是
    1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3
    大的数是 1 。‍

    N,M<=50000,N,M<=50000
    a<=b<=N
    1操作中abs(c)<=N
    2操作中c<=Maxlongint

    整体二分

    注意是第$K$大而不是第$K$小

    数据有负数要离散化

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int n = 0;
        bool flag = false;
        while(*++ptr < '0' || *ptr > '9') if(*ptr == '-') flag = true;
        while(*ptr <= '9' && *ptr >= '0') n = (n << 1) + (n << 3) + (*ptr++ & 15);
        return flag ? -n : n;
    }
    typedef long long LL;
    const int maxn = 50000 + 10, maxm = 50000 + 10;
    int n, m;
    int num[maxm], ref[maxm], num_cnt;
    struct Bit{
        LL c1[maxn], c2[maxn];
        Bit(){
            memset(c1, 0, sizeof(c1));
            memset(c2, 0, sizeof(c2));
        }
        void Update(const int &pos, const LL &v1){
            LL v2 = (pos - 1) * v1;
            for(int i = pos; i <= n; i += i & -i){
                c1[i] += v1;
                c2[i] += v2;
            }
        }
        LL Query(const int &pos){
            LL s1 = 0, s2 = 0;
            for(int i = pos; i; i -= i & -i){
                s1 += c1[i];
                s2 += c2[i];
            }
            return pos * s1 - s2;
        }
    }bit;
    inline void Update(const int &l, const int &r, const LL &val){
        bit.Update(l, val);
        bit.Update(r + 1, -val);
    }
    inline LL Query(const int &l, const int &r){
        return bit.Query(r) - bit.Query(l - 1);
    }
    struct Que{
        int l, r, id;
        LL v;
        Que(){}
        Que(int _l ,int _r, LL _v, int _id): l(_l), r(_r), v(_v), id(_id){}
    }q[maxm];
    bool mark[maxm];
    int f[maxm], g[maxm];
    int ans[maxm], ans_cnt = 0;
    void solve(int ql, int qr, int vl, int vr){
        if(ql > qr) return;
        if(vl == vr){
            for(int i = ql; i <= qr; i++)
                ans[q[f[i]].id] = vl;
            return;
        }
        int mid = vl + vr + 1 >> 1, cnt = 0;
        LL t;
        for(int i = ql; i <= qr; i++){
            if(!q[f[i]].id){
                if(q[f[i]].v >= mid){
                    Update(q[f[i]].l, q[f[i]].r, 1);
                    mark[i] = true;
                    cnt++;
                }
                else mark[i] = false;
            }
            else{
                t = Query(q[f[i]].l, q[f[i]].r);
                if(t < q[f[i]].v){
                    mark[i] = false;
                    q[f[i]].v -= t;
                }
                else{
                    mark[i] = true;
                    cnt++;
                }
            }
        }
        int ll = ql, rr = ql + cnt;
        for(int i = ql; i <= qr; i++)
            if(mark[i]){
                g[ll++] = f[i];
                if(!q[f[i]].id) Update(q[f[i]].l, q[f[i]].r, -1);
            }
            else g[rr++] = f[i];
        for(int i = ql; i <= qr; i++) f[i] = g[i];
        solve(ql, ll - 1, mid, vr);
        solve(ll, qr, vl, mid - 1);
    }
    int main(){
        FILE* fin_handle = fopen("in.txt", "r");
        buf[fread(buf, sizeof(char), sizeof(buf), fin_handle)] = 0;
        freopen("out.txt", "w", stdout);
        n = readint();
        m = readint();
        for(int opt, a, b, c, i = 1; i <= m; i++){
            opt = readint();
            a = readint();
            b = readint();
            c = readint();
            if(opt == 1){
                q[i] = Que(a, b, (LL)c, 0);
                num[++num_cnt] = c;
            }
            else q[i] = Que(a, b, (LL)c, ++ans_cnt);
        }
        sort(num + 1, num + num_cnt + 1);
        num_cnt = unique(num + 1, num + num_cnt + 1) - (num + 1);
        for(int t, i = 1; i <= m; i++)
            if(!q[i].id){
                t = lower_bound(num + 1, num + num_cnt + 1, q[i].v) - num;
                ref[t] = q[i].v;
                q[i].v = t;
            }
        for(int i = 1; i <= m; i++) f[i] = i;
        solve(1, m, 1, num[num_cnt]);
        for(int i = 1; i <= ans_cnt; i++)
            printf("%d
    ", ref[ans[i]]);
        return 0;
    }
  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7647519.html
Copyright © 2011-2022 走看看