Loading

Gym-101470C

Most Influential Pumpkin

题意

\(n\) 个元素的数组 \(A\)\(k\) 次操作,每次操作使得区间 \([L_i,R_i]\) 内的数加 1,每次操作后你都要输出当前 \(A\) 数组的中位数。

\(1 \le n,k \le 6e4\) , \(n\) 是奇数

思路

因为每次只进行加一操作,所以答案只可能是上一次的答案或者上一次的答案加 1.

开一个数组 \(B\) ,初始化 \(B=A\) ,然后将 \(B\) 分块,使得 \(B\) 在块内有序。先处理出初始中位数 \(Ans\)

对于每一次操作,小块里的直接暴力修改 \(A\) ,然后暴力重构 \(B\) ,对于连续的完整块,开一个标记数组 \(tag\) 表示该块全体增加了多少。

对于每一次的答案,我们可以询问 \(B\) 内小于等于 \(Ans\) 的数的个数,若小于 \(\lceil \dfrac n 2 \rceil\)\(Ans\) 加 1. (\(O(\sqrt nlog\sqrt n)\))

/*
 * @Author: zhl
 * @LastEditTime: 2021-03-10 21:36:31
 */
#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
int n, m, A[N], id[N], B[N], l[N], r[N], tag[N];
void block_sort(int idx) {
    for (int i = l[idx];i <= r[idx];i++)B[i] = A[i];
    sort(B + l[idx], B + r[idx] + 1);
}
void build() {
    int len = sqrt(n);
    for (int i = 1;i <= n;i++)id[i] = (i + len - 1) / len;
    for (int i = id[1];i <= id[n];i++) {
        l[i] = len * (i - 1) + 1;
        r[i] = len * i;
        tag[i] = 0;
    }
    r[id[n]] = n;
    for (int i = id[1];i <= id[n];i++)block_sort(i);
}
void updt(int L, int R) {
    for (int idx = id[L] + 1;idx <= id[R] - 1;idx++)tag[idx]++;
    if (id[L] == id[R]) {
        for (int i = L;i <= R;i++)A[i]++;
        block_sort(id[L]);
    }
    else {
        for (int i = L;i <= r[id[L]];i++)A[i]++;
        block_sort(id[L]);
        for (int i = l[id[R]];i <= R;i++)A[i]++;
        block_sort(id[R]);
    }
}
int cal(int v) {
    int res = 0;
    for (int idx = id[1];idx <= id[n];idx++) {
        res += upper_bound(B + l[idx], B + r[idx] + 1, v - tag[idx]) - (B + l[idx]);
    }
    return res;
}
int main() {
#ifdef ONLINE_JUDGE
    freopen("f.in", "r", stdin);
    //freopen("out.txt","w",stdout);
#endif
    while (~scanf("%d%d", &n, &m) and n + m) {
        for (int i = 1;i <= n;i++)scanf("%d", A + i), B[i] = A[i];
        int mid = (n + 1) / 2;
        sort(B + 1, B + 1 + n);
        int ans = B[mid];
        build();
        for (int i = 1, L, R;i <= m;i++) {
            scanf("%d%d", &L, &R);
            updt(L, R);
            if (cal(ans) < mid)ans++;

            printf("%d\n", ans);;
        }
    }
}
/*
1 1
1
1 1
3 4
3 2 1
1 3
1 1
3 3
3 3
0 0


7 7
1 1 1 3 3 3 3
1 3
5 7
1 3
1 4
1 3
4 4
1 3
0 0

 */
posted @ 2021-03-11 10:16  —O0oO-  阅读(97)  评论(0编辑  收藏  举报