第十三届北航程序设计竞赛决赛网络同步赛 B题 校赛签到(建树 + 打标记)
题目链接 校赛签到
对每个操作之间建立关系。
比较正常的是前$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;
}

浙公网安备 33010602011771号