/*
考虑直接使用暴力来算的话 SG[i]表示以i为根的子树的SG值, 然后考虑枚举删除那个子树节点, 然后求拆成的树的sg异或值, 求mex即可 复杂度三次方 然后考虑尝试 整体来做 发现对于每次子树的合并, 每棵子树种的sg值相当是异或了其他的所有子树 而这个东西显然是可以用 线段树合并来维护的 最后找出所有sg不为0的点即可 */
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#define ll long long
#define M 100010
#define mmp make_pair
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
int cor[M], cov[M * 60], laz[M * 60], ls[M * 60], rs[M * 60], rt[M], n, sg[M], cnt, ans[M], tot;
vector<int> to[M]; void add(int &now, int v, int deep) {
if(deep <= -1) return;
if(v & (1 << deep)) swap(ls[now], rs[now]);
laz[now] ^= v;
} void pushdown(int now, int deep) {
if(!laz[now] || !now) return;
add(ls[now], laz[now], deep - 1);
add(rs[now], laz[now], deep - 1);
laz[now] = 0;
} int merge(int now, int last, int deep) {
if(!now || !last) return now | last;
if(deep == -1) {
cov[now] |= cov[last];
return now;
}
pushdown(now, deep), pushdown(last, deep);
ls[now] = merge(ls[now], ls[last], deep - 1);
rs[now] = merge(rs[now], rs[last], deep - 1);
cov[now] = cov[ls[now]] && cov[rs[now]];
return now;
} void insert(int &now, int v, int deep) {
if(!now) now = ++cnt;
if(deep == -1) {
cov[now] = 1;
return;
}
if(v & (1 << deep)) insert(rs[now], v, deep - 1);
else insert(ls[now], v, deep - 1);
} int mex(int now, int deep) {
if(!now || deep == -1) return 0;
pushdown(now, deep);
if(!cov[ls[now]]) return mex(ls[now], deep - 1);
else return (1 << deep) + mex(rs[now], deep - 1);
} void dfs(int now, int fa) {
int tmp = 0;
for(int i = 0; i < to[now].size(); i++) {
int vj = to[now][i];
if(vj == fa) continue;
dfs(vj, now);
tmp ^= sg[vj];
}
if(!cor[now]) insert(rt[now], tmp, 17);
for(int i = 0; i < to[now].size(); i++) {
int vj = to[now][i];
if(vj == fa) continue;
add(rt[vj], tmp ^ sg[vj], 17);
rt[now] = merge(rt[now], rt[vj], 17);
}
sg[now] = mex(rt[now], 17);
} void get(int now, int fa, int anss) {
for(int i = 0; i < to[now].size(); i++) {
int vj = to[now][i];
if(vj == fa) continue;
anss ^= sg[vj];
}
if(anss == 0 && !cor[now]) ans[++tot] = now;
for(int i = 0; i < to[now].size(); i++) {
int vj = to[now][i];
if(vj == fa) continue;
get(vj, now, anss ^ sg[vj]);
}
} int main() {
n = read();
for(int i = 1; i <= n; i++) cor[i] = read();
for(int i = 1; i < n; i++) {
int vi = read(), vj = read();
to[vi].push_back(vj);
to[vj].push_back(vi);
}
dfs(1, 0);
get(1, 0, 0);
if(tot) {
sort(ans + 1, ans + tot + 1);
for(int i = 1; i <= tot; i++) cout << ans[i] << '\n';
} else puts("-1");
return 0;
}

SPOJ COT3 - Combat on a tree的更多相关文章

  1. SPOJ COT3 Combat on a tree(Trie树、线段树的合并)

    题目链接:http://www.spoj.com/problems/COT3/ Alice and Bob are playing a game on a tree of n nodes.Each n ...

  2. SPOJ COT3.Combat on a tree(博弈论 Trie合并)

    题目链接 \(Description\) 给定一棵\(n\)个点的树,每个点是黑色或白色.两个人轮流操作,每次可以选一个白色的点,将它到根节点路径上的所有点染黑.不能操作的人输,求先手是否能赢.如果能 ...

  3. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  4. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  5. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  6. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  7. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

  8. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  9. 【SPOJ】QTREE7(Link-Cut Tree)

    [SPOJ]QTREE7(Link-Cut Tree) 题面 洛谷 Vjudge 题解 和QTREE6的本质是一样的:维护同色联通块 那么,QTREE6同理,对于两种颜色分别维护一棵\(LCT\) 每 ...

随机推荐

  1. [转]java虚拟机工作原理详解

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...

  2. STL 的 vector 根据元素的值来删除元素的方法

    vector 的 erase( ) 只能删除迭代器,所以要想删某种值的元素,需要这样: 假设有一个 vector 叫 vt ,则 vt.erase( remove( vt.begin() , vt.e ...

  3. postman测试post请求参数为json类型

    1. 设置Headers Content-Type类型为application/json 2.Body 设置如下.请求的数据类型为Json格式

  4. Pullword 分词工具

    def get_response(self, txt): """ 热词工具 """ datas = [] request_lists = [ ...

  5. 关于Zookeeper选举机制

    zookeeper集群 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点和redis是相同的,即对客户端来讲每个服 ...

  6. mysql获取某个表的所有属性名及其数据

    MYSQL类实现从数据库相应的表中获取所有属性及其数据,数据为元组类型.返回结果存放在字典中 import pymysql class MYSQL: def __init__(self): pass ...

  7. PyQt5显示一个空白的窗口

    效果如下图: """ In this example, we create a simple window in PyQt5. """ # ...

  8. Ngui Tween 组合动画 group

    使用NGUI的Tween做补间动画,难免会涉及组合各种Tween.最常用的就是 Scale+Alpha组合 做淡入淡出了.那么如何控制 播放完一个Tween 后在 播放另一个Tween呢? 利用del ...

  9. 【转】XP_cmdshell存储过程

    原文地址:http://www.cnblogs.com/love_study/archive/2010/03/02/1676583.html 一 .简介 xp_cmdshell 扩展存储过程将命令字符 ...

  10. Zabbix agentd 命令

    #zabbix_agentd -p 查看zabbix所有的内置监控项 [root@nod01 zabbix_agentd.d]# zabbix_agentd -pagent.hostname [s|Z ...