zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    cvBox2D和RotatedRect中返回的角度angle详解
    opencv源码阅读之——iOS的两条接口UIImageToMat()和MatToUIImage()
    3、设置jsp上的类容自动更新
    2、搭建一个简单的Web项目
    1、IDEA的常用快捷键
    2、jQuery的Ajax简单示例
    1、jQuery的使用入门
    13、Ajax的使用
    JSP和后台交互时的乱码问题
    12、Filter(拦截器)
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11732538.html
Copyright © 2011-2022 走看看