设$f[x]$为$x$子树里的子游戏的sg值,$h[x]$为$x$所有儿子节点$f[x]$的异或和,则:

$f[x]=mex(y到x路径上所有点的h的异或和\ xor\ y到x路径上所有点的f的异或和)$,$y$是$x$子树中的一个白点。

考虑一个白点对其祖先的影响,可以发现每往上走一步,一个子树里的贡献将会异或上一个相同的数。

用Trie来维护每个点子树里所有白点的贡献,需要支持合并操作、mex的查询,以及一个异或的标记,下传时交换左右儿子。

时间复杂度$O(n\log n)$。

#include<cstdio>
const int N=100010,M=4000000;
int n,m,i,x,y,a[N],g[N],v[N<<1],nxt[N<<1],ed,f[N],h[N];
int l[M],r[M],tag[M],T[N],tot;bool val[M],fin[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void rev(int d,int p,int x){
if(!x||d<0)return;
tag[x]^=p;
if(p>>d&1){int t=l[x];l[x]=r[x];r[x]=t;}
}
inline void pb(int d,int x){if(tag[x])rev(d-1,tag[x],l[x]),rev(d-1,tag[x],r[x]),tag[x]=0;}
int build(int d,int p){
int x=++tot;
if(d<0)return val[x]=1,x;
if(p>>d&1)r[x]=build(d-1,p);else l[x]=build(d-1,p);
return x;
}
int merge(int d,int p,int x,int y){
if(!y)return x;
if(!x){
rev(d,p,y);
return y;
}
int z=++tot;
if(d<0)return val[z]=1,z;
pb(d,x),pb(d,y);
if(p>>d&1)l[z]=merge(d-1,p,l[x],r[y]),r[z]=merge(d-1,p,r[x],l[y]);
else l[z]=merge(d-1,p,l[x],l[y]),r[z]=merge(d-1,p,r[x],r[y]);
return val[z]=val[l[z]]&val[r[z]],z;
}
inline int mex(int x){
int t=0;
for(int i=m;~i;i--){
pb(i,x);
if(!val[l[x]])x=l[x];else x=r[x],t|=1<<i;
}
return t;
}
void dfs(int x,int y){
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x),h[x]^=f[v[i]];
if(!a[x])T[x]=build(m,h[x]);
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)T[x]=merge(m,h[x]^f[v[i]],T[x],T[v[i]]);
f[x]=mex(T[x]);
}
void cal(int x,int y,int z){
z^=f[x]^h[x];
if(!a[x]&&!z)fin[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)cal(v[i],x,z);
}
int main(){
for(read(n),i=1;i<=n;i++)read(a[i]);
for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
while((1<<m)<=n)m++;m--;
dfs(1,0);
if(!f[1])return puts("-1"),0;
for(cal(i=1,0,f[1]);i<=n;i++)if(fin[i])printf("%d\n",i);
return 0;
}

  

最新文章

  1. android copy项目后修改项目名
  2. 2016huasacm暑假集训训练五 H - Coins
  3. python时间格式化
  4. VC++ 6.0使用定时器SetTimer;
  5. 基于Hadoop 2.6.0运行数字排序的计算
  6. 夺命雷公狗—angularjs—11—service的基本概念
  7. Android IOS WebRTC 音视频开发总结(二四)-- p2p调用堆栈
  8. NPOI Excel导入 导出
  9. 深入理解计算机系统第二版习题解答CSAPP 2.11
  10. java学习笔记(12) —— Struts2 通过 xml /json 实现简单的业务处理
  11. MyEclipse添加ibatis DTD文件实现xml的自动提示功能
  12. JavaScript获取元素CSS计算后的样式
  13. go的gin框架从请求中获取参数的方法
  14. 微软URLRewriter.dll的url重写在目标框架.Net Framework2.0、4.0和应用程序池经典模式、集成模式下的配置
  15. 可重入锁 &amp; 不可重入锁
  16. RxJava2 源码解析(一)
  17. Factory Method
  18. vm安装diagram
  19. 10.Solr4.10.3数据导入(DIH全量增量同步Mysql数据)
  20. Swift 里字符串(七)stringIndex

热门文章

  1. [codeforces 293]A. Weird Game
  2. 对原型prototype的详解
  3. Java数据库ResultSet转json实现
  4. jquery.fileupload.js 杂记
  5. mysql in 子查询 效率慢 优化(转)
  6. Java RMI 框架
  7. Convert Sorted List to Balanced BST
  8. 更改Apache默认网站根目录
  9. codeforces B. Petya and Staircases 解题报告
  10. JavaScript设计模式 - 单例模式