1. 程式人生 > >第十三屆北航程序設計競賽決賽網絡同步賽 B題 校賽簽到(建樹 + 打標記)

第十三屆北航程序設計競賽決賽網絡同步賽 B題 校賽簽到(建樹 + 打標記)

結點 http rac through pla ace print 簽到 read

題目鏈接 校賽簽到

對每個操作之間建立關系。

比較正常的是前$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;
}

  

第十三屆北航程序設計競賽決賽網絡同步賽 B題 校賽簽到(建樹 + 打標記)