[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\n", ref[ans[i]]);
    return 0;
}

 

posted @ 2017-10-10 19:57  jzyy  阅读(124)  评论(0编辑  收藏  举报