[CF1010D]Mars Over_位运算性质

Mars rover

题目链接http://codeforces.com/problemset/problem/1010/D

数据范围:略。


题解

因为每次只改一个,改完之后改回去,这个性质很重要。

发现有些叶子更改了之后,整体的答案是不变的,因为会出现:他的父亲是$&$操作但是另一个儿子是$0$这种...

故此,我们先算出一个节点都不更改时,每个节点的值。

之后我们通过位运算,对每一个节点维护一个$tag$表示这个节点更改会不会影响到根节点。

遍历即可,细节可以看代码。

代码

#include <bits/stdc++.h>

#define N 1000010 

#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) 

using namespace std;

char s[10];

int opt[N], val[N], ch[N][2];

bool tag[N];

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0, f = 1;
	char c = nc();
	while (c < '0' || c > '9') {
		if (c == '-')
			f = -1;
		c = nc();
	}
	while (c >= '0' && c <= '9') {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

void dfs(int p) {
	int ls = ch[p][0], rs = ch[p][1];
	if (opt[p] == 1) {
		return;
	}
	else if (opt[p] == 2) {
		dfs(ch[p][0]);
		val[p] = !val[ls];
	}
	else if (opt[p] == 3) {
		dfs(ls), dfs(rs);
		val[p] = val[ls] ^ val[rs];
	}
	else if (opt[p] == 4) {
		dfs(ls), dfs(rs);
		val[p] = val[ls] & val[rs];
	}
	else {
		dfs(ls), dfs(rs);
		val[p] = val[ls] | val[rs];
	}
}

void dfs2(int p) {
	int ls = ch[p][0], rs = ch[p][1];
	if (!tag[p]) {
		if (ls) {
			tag[ls] = false;
		}
		if (rs) {
			tag[rs] = false;
		}
	}
	else {
		if (opt[p] == 1) {
			return;
		}
		else if (opt[p] == 2) {
			tag[ls] = true;
		}
		else if (opt[p] == 3) {
			tag[ls] = tag[rs] = true;
		}
		else if (opt[p] == 5) {
			tag[ls] = (val[rs] ? false : true);
			tag[rs] = (val[ls] ? false : true);
		}
		else {
			tag[ls] = (val[rs] ? true : false);
			tag[rs] = (val[ls] ? true : false);
		}
	}
	if (ls) {
		dfs2(ls);
	}
	if (rs) {
		dfs2(rs);
	}
}

int main() {
	// setIO("b");
	memset(tag, true, sizeof tag);
	int n = rd();
	/*
	1 -> IN
	2 -> Not
	3 -> Xor
	4 -> And
	5 -> Or
	*/
	for (int i = 1; i <= n; i ++ ) {
		char c = nc();
		while (c != 'I' && c != 'N' && c != 'X' && c != 'A' && c != 'O') {
			c = nc();
		}
		if (c == 'I') {
			val[i] = rd();
			opt[i] = 1;
		}
		else if (c == 'N') {
			ch[i][0] = rd();
			opt[i] = 2;
		}
		else if (c == 'X') {
			ch[i][0] = rd(), ch[i][1] = rd();
			opt[i] = 3;
		}
		else if (c == 'A') {
			ch[i][0] = rd(), ch[i][1] = rd();
			opt[i] = 4;
		}
		else {
			ch[i][0] = rd(), ch[i][1] = rd();
			opt[i] = 5;
		}
	}
	// for (int i = 1; i <= n; i ++ ) {
	// 	printf("%d ", opt[i]);
	// }
	// puts("");

	dfs(1);
	// for (int i = 1; i <= n; i ++ ) {
	// 	printf("%d", val[i]);
	// }
	// puts("");

	dfs2(1);
	// for (int i = 1; i <= n; i ++ ) {
	// 	if (tag[i]) {
	// 		putchar('1'), putchar(' ');
	// 	}
	// 	else {
	// 		putchar('0'), putchar(' ');
	// 	}
	// }

	for (int i = 1; i <= n; i ++ ) {
		if (opt[i] == 1) {
			if (val[1] ^ tag[i]) {
				putchar('1'); 
			}
			else {
				putchar('0');
			}
		}
	}
	fclose(stdin), fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/ShuraK/p/11732538.html