[CF707D] Persistent Bookcase - 离线处理

[CF707D] Persistent Bookcase

Description

维护一个二维零一矩阵(\(n,m \le 1000\)),支持四种操作(不超过 \(10^5\) 次),将 (i,j) 置一,将 (i,j) 置零,将第 i 行零一反转,回到第 K 次操作前的状态。每次操作后输出全局一共有多少个一。

Solution

对操作过程建树,然后 DFS

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1005;

bitset<N> a[N];
tuple<int, int, int> op[N * N];
vector<int> g[N * N];
int n, m, q, ans[N * N];

int cur = 0;

void dfs(int p)
{
    auto [x, y, z] = op[p];
    int old = a[min(1000ll, y)][z];
    if (x == 1)
    {
        if (a[y][z] == 0)
            ++cur;
        a[y][z] = 1;
    }
    if (x == 2)
    {
        if (a[y][z] == 1)
            --cur;
        a[y][z] = 0;
    }
    if (x == 3)
    {
        cur -= a[y].count();
        a[y].flip();
        if (a[y][N - 1])
            cur -= N - m;
        else
            cur += N - m;
        cur += a[y].count();
    }
    ans[p] = cur;
    for (int q : g[p])
        dfs(q);
    if (x == 1)
    {
        a[y][z] = old;
        if (a[y][z] == 0)
            --cur;
    }
    if (x == 2)
    {
        a[y][z] = old;
        if (a[y][z] == 1)
            ++cur;
    }
    if (x == 3)
    {
        cur -= a[y].count();
        a[y].flip();
        if (a[y][N - 1])
            cur -= N - m;
        else
            cur += N - m;
        cur += a[y].count();
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for (int i = 1; i <= q; i++)
    {
        int t1, t2, t3 = 0;
        cin >> t1 >> t2;
        if (t1 < 3)
            cin >> t3;
        op[i] = {t1, t2, t3};
        if (t1 == 4)
            g[t2].push_back(i);
        else
            g[i - 1].push_back(i);
    }
    dfs(0);
    for (int i = 1; i <= q; i++)
    {
        cout << ans[i] << endl;
    }
}
上一篇:Interlij 无法使用中文输入法解决方法(适用于Interlij全家桶 Linux环境)


下一篇:vim 命令 ,操作,快捷键 记录