Submission #101808

#TimeUsernameProblemLanguageResultExecution timeMemory
101808KCSCCats or Dogs (JOI18_catdog)C++14
100 / 100
387 ms36732 KiB
#include <bits/stdc++.h>
using namespace std;

const int DIM = 100005;
const int INF = 1000000005;

struct Matrix {
	long long dp[2][2];
	
	Matrix operator *(const Matrix &other) {
		Matrix result;
		for (int i1 = 0; i1 <= 1; ++i1) {
		for (int j2 = 0; j2 <= 1; ++j2) {
			long long aux = 1LL * INF * INF;
			for (int j1 = 0; j1 <= 1; ++j1) {
			for (int i2 = 0; i2 <= 1; ++i2) {
				aux = min(aux, (*this).dp[i1][j1] + other.dp[i2][j2] + (j1 != i2)); } }
			result.dp[i1][j2] = aux; } } 
		return result; }
}; 

int szt[DIM], msk[DIM], wtc[DIM], pic[DIM], ftc[DIM];
vector<Matrix> sgt[DIM]; vector<int> chn[DIM], edg[DIM];

void preDfs(int x, int f, int &m) {	
	int big = 0; szt[x] = 1;
	for (int y : edg[x]) if (y != f) {
		preDfs(y, x, m); szt[x] += szt[y];
		if (!big or szt[big] < szt[y]) {
			big = y; } }
	if (!big) {
		wtc[x] = ++m; }
	else {
		wtc[x] = wtc[big];
		for (int y : edg[x]) 
			if (y != f and y != big) {
				ftc[wtc[y]] = x; } }
	chn[wtc[x]].push_back(x); }

void build(int ch, int nd, int le, int ri) {
	if (le == ri) {
		sgt[ch][nd].dp[0][0] = sgt[ch][nd].dp[1][1] = 0;
		sgt[ch][nd].dp[0][1] = sgt[ch][nd].dp[1][0] = INF; }
	else {
		int md = (le + ri) >> 1;
		build(ch, nd << 1, le, md);
		build(ch, nd << 1 | 1, md + 1, ri);
		sgt[ch][nd] = sgt[ch][nd << 1] * sgt[ch][nd << 1 | 1]; } }

void update(int ch, int nd, int le, int ri, int ps, long long vl, long long vr) {
	if (le == ri) {
		sgt[ch][nd].dp[0][0] += vl; sgt[ch][nd].dp[1][1] += vr; }
	else {
		int md = (le + ri) >> 1;
		if (ps <= md) {
			update(ch, nd << 1, le, md, ps, vl, vr); }
		else {
			update(ch, nd << 1 | 1, md + 1, ri, ps, vl, vr); }
		sgt[ch][nd] = sgt[ch][nd << 1] * sgt[ch][nd << 1 | 1]; } }

void updateChain(int x, long long vl, long long vr) {
	int ch = wtc[x];
	long long vl1 = min(sgt[ch][1].dp[0][0], sgt[ch][1].dp[0][1]),
			  vr1 = min(sgt[ch][1].dp[1][0], sgt[ch][1].dp[1][1]);
	update(ch, 1, 1, chn[ch][0], pic[x], vl, vr);
	long long vl2 = min(sgt[ch][1].dp[0][0], sgt[ch][1].dp[0][1]),
			  vr2 = min(sgt[ch][1].dp[1][0], sgt[ch][1].dp[1][1]);
 	if (ftc[ch]) {
		updateChain(ftc[ch], min(vl2, vr2 + 1) - min(vl1, vr1 + 1), 
							 min(vr2, vl2 + 1) - min(vr1, vl1 + 1)); } }

void initialize(int n, vector<int> end1, vector<int> end2) {
	for (int i = 1; i < n; ++i) {
		int x = end1[i - 1], y = end2[i - 1];
		edg[x].push_back(y); edg[y].push_back(x); }
	int m = 0; preDfs(1, 0, m);
	for (int i = 1; i <= m; ++i) {
		chn[i].push_back(chn[i].size());
		reverse(chn[i].begin(), chn[i].end());
		sgt[i].resize(chn[i][0] << 2);
		for (int j = 1; j <= chn[i][0]; ++j) {	
			pic[chn[i][j]] = j; }
		build(i, 1, 1, chn[i][0]);  } }

inline int answer(void) {
	int ch = wtc[1]; long long mn = 1LL * INF * INF;
	for (int i = 0; i <= 1; ++i) {
	for (int j = 0; j <= 1; ++j) {
		mn = min(mn, sgt[ch][1].dp[i][j]); } }
	return mn; }

int cat(int x) {
	updateChain(x, INF, 0); msk[x] = 1;
	return answer(); }

int dog(int x) {
	updateChain(x, 0, INF); msk[x] = 2; 
	return answer(); }

int neighbor(int x) {
	if (msk[x] == 1) {
		updateChain(x, -INF, 0); }
	else {
		updateChain(x, 0, -INF); }
	return answer(); }

#ifdef HOME
int main(void) {
	freopen("catdog.in", "r", stdin);
	freopen("catdog.out", "w", stdout);
	int n; cin >> n;
	vector<int> a(n - 1), b(n - 1);
	for (int i = 0; i <= n - 2; ++i) {
		cin >> a[i] >> b[i]; }
	initialize(n, a, b);
	int q; cin >> q;
	while (q--) {
		int t, x; cin >> t >> x;
		if (t == 1) { cout << cat(x) << endl; }
		if (t == 2) { cout << dog(x) << endl; }
		if (t == 3) { cout << neighbor(x) << endl; } }
	return 0; }
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...