bzoj 4134 ljw和lzr的hack比赛
来源:互联网 发布:python网络爬虫是什么 编辑:程序博客网 时间:2024/06/05 19:43
Trie树维护Sg值,类似线段树合并的方式合并子树,复杂度 O(nlog(n))
/************************************************************** Problem: 4134 User: Clare Language: C++ Result: Accepted Time:1988 ms Memory:73476 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>using namespace std; #define N 100010 int n,m;int A[N],f[N],h[N],C[40],root[N];struct Edge{ int to,next;}edge[N*2];int head[N],Tot;struct Node{ int l,r,flag; bool Full,Be_ans;}t[N*40];int tot; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return x*f;} void Addedge(int u,int v){ Tot++;edge[Tot].next=head[u];edge[Tot].to=v;head[u]=Tot; Tot++;edge[Tot].next=head[v];edge[Tot].to=u;head[v]=Tot;} void Rev(int Floor,int k,int x){ if(!x||Floor<0) return; t[x].flag^=k; if(k&C[Floor]) swap(t[x].l,t[x].r);} void Pushdown(int Floor,int x){ if(t[x].flag) { Rev(Floor-1,t[x].flag,t[x].l); Rev(Floor-1,t[x].flag,t[x].r); t[x].flag=0; }} int Build(int Floor,int k){ int now=++tot; if(Floor<0) { t[now].Full=1; return now; } if(k&C[Floor]) t[now].r=Build(Floor-1,k); else t[now].l=Build(Floor-1,k); return now;} int Merge(int Floor,int k,int x,int y){ if(!y) return x; if(!x) { Rev(Floor,k,y); return y; } int now=++tot; if(Floor<0) { t[now].Full=1; return now; } Pushdown(Floor,x);Pushdown(Floor,y); if(k&C[Floor]) { t[now].l=Merge(Floor-1,k,t[x].l,t[y].r); t[now].r=Merge(Floor-1,k,t[x].r,t[y].l); } else { t[now].l=Merge(Floor-1,k,t[x].l,t[y].l); t[now].r=Merge(Floor-1,k,t[x].r,t[y].r); } t[now].Full=t[t[now].l].Full&t[t[now].r].Full; return now;} int Mex(int Floor,int x){ if(Floor<0) return 0; Pushdown(Floor,x); if(!t[t[x].l].Full) { x=t[x].l; return Mex(Floor-1,x); } else { x=t[x].r; return C[Floor]+Mex(Floor-1,x); }} void DFS(int k,int fa){ for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(v==fa) continue; DFS(v,k); h[k]^=f[v]; } if(!A[k]) root[k]=Build(m,h[k]); for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(v==fa) continue; root[k]=Merge(m,h[k]^f[v],root[k],root[v]); } f[k]=Mex(m,root[k]);} void Find(int k,int fa,int ans){ ans^=h[k]^f[k]; if(!A[k]&&!ans) t[k].Be_ans=true; for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(v==fa) continue; Find(v,k,ans); }} int main(){ C[0]=1; for(int i=1;i<=30;i++) C[i]=C[i-1]<<1; n=read(); for(int i=1;i<=n;i++) A[i]=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); Addedge(x,y); } while(C[m]<=n)m++; m--; DFS(1,0); if(!f[1]) { printf("-1\n"); } else { Find(1,0,f[1]); for(int i=1;i<=n;i++) { if(t[i].Be_ans) printf("%d\n",i); } } return 0;}
0 0
- bzoj 4134 ljw和lzr的hack比赛
- [bzoj4134]ljw和lzr的hack比赛
- BZOJ4134 ljw和lzr的hack比赛
- bzoj 4134: ljw和lzr的hack比赛 sg函数+字典树合并
- [BZOJ4134][JZOJ4401]ljw和lzr的hack比赛
- 【BZOJ4134】【树上博弈】【博弈论】【线段树合并】ljw和lzr的hack比赛 题解
- [BZOJ 3752]Hack
- !improtant和*的css hack
- BZOJ 3139: [Hnoi2013]比赛
- BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
- BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
- CSS HACK和浏览器兼容问题的解决方法
- CSS Hack和向后兼容的常见问题
- struct hack和灵活的数组成员
- IE10、IE11和Microsoft Edge的Hack
- HTMl和css的hack技术常识
- BZOJ 3903 比赛 最小割
- HNIO 2013 bzoj 3139 比赛
- OpenVirtualization otzon 学习笔记
- ngnix的安装小记
- mm编译 问题
- VS生成DLL没有生成LIB文件的解决方法
- JVM系列之JVM体系(一)
- bzoj 4134 ljw和lzr的hack比赛
- ImageSpan的使用
- swift-基本操作02-自增和复合赋值运算符
- 新技能get√丨抢了那么多红包,你知道算法是怎么实现的吗
- label 根据内容text确定控件的大小 分为单行/多行文字
- Music
- MySQL中select * for update锁表的问题(悲观锁)
- matlab 扩大虚拟内存
- git查看某次提交/更新所更改的文件