题目链接 校赛签到
对每个操作之间建立关系。
比较正常的是前$3$种操作,若第$i$个操作属于前$3$种,那么就从操作$i-1$向$i$连一条有向边。
比较特殊的是第$4$种操作,若第$i$个操作属于第$4$种这个时候我们需要从操作$k$向操作$i$连一条有向边。
那么一共有$q+1$个结点,$q$条边,很明显是一个树的结构。$0$号点为根结点。
那么从根结点出发,依次操作就可以了~,遇到操作$3$则打标记
我太懒 用bitset + fread挂过去了。
时间复杂度$O(\frac{mq}{w})$
#include <bits/stdc++.h> namespace IO{ const int MT = 30 * 1024 * 1024; char IO_BUF[MT]; int IO_PTR, IO_SZ; void begin(){ IO_PTR = 0; IO_SZ = fread (IO_BUF, 1, MT, stdin); } template<typename T> inline bool scan_d (T & t){ while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != ‘-‘ && (IO_BUF[IO_PTR] < ‘0‘ || IO_BUF[IO_PTR] > ‘9‘))IO_PTR ++; if (IO_PTR >= IO_SZ) return false; bool sgn = false; if (IO_BUF[IO_PTR] == ‘-‘) sgn = true, IO_PTR ++; for (t = 0; IO_PTR < IO_SZ && ‘0‘ <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= ‘9‘; IO_PTR ++) t = t * 10 + IO_BUF[IO_PTR] - ‘0‘; if (sgn) t = -t; return true; } }; using namespace std; using namespace IO; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 2e5 + 4; const int Q = 1e3 + 2; const LL mod = 100624; vector <int> v[N]; LL p[N]; struct node{ int ty, x, y, z; } op[N]; int T; int ret[N]; int n, m, q; int c[N]; bitset <Q> a[Q]; inline int calc(int x){ return (a[x] >> 1).count() - (a[x] >> (m + 1)).count(); } void dfs(int x, int cnt){ ret[x] = cnt; for (auto u : v[x]){ if (op[u].ty == 1){ int nx = op[u].x, ny = op[u].y, nz = op[u].z; if (c[nx] == 0){ int z = a[nx][ny], num = calc(nx); a[nx][ny] = nz; dfs(u, cnt + calc(nx) - num); a[nx][ny] = z; } else{ int z = a[nx][m - ny + 1], num = calc(nx); a[nx][m - ny + 1] = nz; dfs(u, cnt + calc(nx) - num); a[nx][m - ny + 1] = z; } } else if (op[u].ty == 2){ int nx = op[u].x; int num = calc(nx); a[nx].flip(); dfs(u, cnt + calc(nx) - num); a[nx].flip(); } else if (op[u].ty == 3){ int nx = op[u].x; c[nx] ^= 1; dfs(u, cnt); c[nx] ^= 1; } else dfs(u, cnt); } } int main(){ begin(); p[0] = 1; rep(i, 1, 2e5 + 1) p[i] = p[i - 1] * 813ll % mod; scan_d(T); while (T--){ scan_d(n); scan_d(m); scan_d(q); rep(i, 0, q + 1) v[i].clear(); rep(i, 0, n + 1) a[i].reset(); rep(i, 1, q){ int et; scan_d(et); if (et == 1){ v[i - 1].push_back(i); int x, y, z; scan_d(x); scan_d(y); scan_d(z); op[i].ty = 1; op[i].x = x; op[i].y = y; op[i].z = z; } else if (et == 2){ v[i - 1].push_back(i); int x; scan_d(x); op[i].ty = 2; op[i].x = x; } else if (et == 3){ v[i - 1].push_back(i); int x; scan_d(x); op[i].ty = 3; op[i].x = x; } else{ int x; scan_d(x); v[x].push_back(i); op[i].ty = 4; } } dfs(0, 0); LL ans = 0; rep(i, 1, q) ans = (ans + ret[i] * p[i] % mod) % mod; printf("%lld\n", ans); } return 0; }