AGC017C. Snuke and Spells

i被消除,当且仅当剩下的数的数目刚好为i,那么模型可以转化为对于i,从第i个位置往前放数,表示cast a spell of i时能把这一块都消去,对于没有数的空白显然需要补上才能愉快地继续消,显然需要修改的次数就是空白的数量。

有修改操作也同样可以维护。

#include <cstdio>
#include <cstring>
const int N = 2e5 + 100;
int num[N], data[N * 2], n, m, a[N], *cnt = data + N;

int main() {
#ifdef lol
    freopen("t.in", "r", stdin);
    freopen("t.out", "w", stdout);
#endif

    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", a + i);
        ++num[a[i]];
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < num[i]; ++j)
            ++cnt[i - j];
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        if (!cnt[i]) ++ans;
    while (m--) {
        int u, v, t;
        scanf("%d%d", &u, &v);
        t = a[u];
        --cnt[t - num[t] + 1];
        if (t - num[t] + 1 > 0  && cnt[t - num[t] + 1] == 0)
            ++ans;
        --num[t];
        ++cnt[v - num[v]];
        if (v - num[v] > 0 && cnt[v - num[v]] == 1)
            --ans;
        ++num[v];
        a[u] = v;
        printf("%d
", ans);
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/ichn/p/7654376.html