题目
样例输入
题解
由于确定了一条边的父子关系,所以当父亲和儿子的颜色不一致时,直接对儿子进行反色操作。因为父亲进步进行反色操作,父与子的颜色还是不一致。
然而我蠢。
我维护了基于dfs的前缀和,本来想画个图l向r+1连条边,结果没有进展。
因为dfs序前面的会影响后面,后面不会影响前面,所以我还打了个线段树,带了个log。
代码长就不说了,递归还爆栈。
另外,看清点数。对于点数n≤5∗105,不要dfs,用bfs/人工栈!!!!
代码(较蠢)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 500010
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
struct sgm{
int sum,lazy;
};sgm tr[N*20];
struct note{
int to,next;
};note edge[N*2];
int val[N],siz[N],ans[N],fa[N];
int dfn[N],tar[N],head[N],head1[N];
int i,j,k,l,n,m,T,temp;
int u,v,tot;
int st[N];
bool bz[N];
int read(){
int res=0,fh=1;char ch;
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return res*fh;
}
void write(int x){
if(x>9)write(x/10);
P(x%10+'0');
}
void lb(int x,int y){
edge[++tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
}
void update(int ps){
tr[ps].sum=tr[ps<<1].sum+tr[(ps<<1)+1].sum;
}
void downld(int ps){
if(tr[ps].lazy!=0){
tr[ps<<1].lazy+=tr[ps].lazy;
tr[(ps<<1)+1].lazy+=tr[ps].lazy;
tr[ps<<1].sum+=tr[ps].lazy;
tr[(ps<<1)+1].sum+=tr[ps].lazy;
tr[ps].lazy=0;
}
}
void dg(){
st[st[0]=1]=1;memcpy(head1,head,sizeof(head1));
bool p;
int x,i;
while(st[0]){
x=st[st[0]];
if(!bz[x]){
dfn[x]=++T;tar[T]=x;siz[x]=1;
bz[x]=1;
}
p=0;
for(i=head1[x];i;i=edge[i].next)
if(fa[x]!=edge[i].to){
fa[edge[i].to]=x;
st[++st[0]]=edge[i].to;
p=1;
head1[x]=edge[i].next;
break;
}
if(!p){
if(st[0]>1)siz[st[st[0]-1]]+=siz[x];
st[0]--;
}
}
}
void build(int ps,int l,int r){
if(l==r){
tr[ps].sum=val[tar[l]];
return;
}
int wz=(l+r)>>1;
build(ps<<1,l,wz);
build((ps<<1)+1,wz+1,r);
update(ps);
}
int find(int ps,int l,int r,int x){
if(l==r)return tr[ps].sum;
downld(ps);
int wz=(l+r)>>1;
if(x<=wz)return find(ps<<1,l,wz,x);
else return find((ps<<1)+1,wz+1,r,x);
update(ps);
}
void change(int ps,int l,int r,int x,int y,int z){
if(l==x && r==y){
tr[ps].sum+=z;
tr[ps].lazy+=z;
return;
}
downld(ps);
int wz=(l+r)>>1;
if(y<=wz)change(ps<<1,l,wz,x,y,z);else
if(x>wz)change((ps<<1)+1,wz+1,r,x,y,z);else{
change(ps<<1,l,wz,x,wz,z);
change((ps<<1)+1,wz+1,r,wz+1,y,z);
}
update(ps);
}
int main(){
n=read();
fo(i,1,n)val[i]=read();
fo(i,1,n-1){
u=read(),v=read();
lb(u,v);lb(v,u);
}
dg();
build(1,1,n);
fo(i,1,n){
temp=find(1,1,n,i);
if(temp&1){
ans[++ans[0]]=tar[i];
change(1,1,n,i,i+siz[tar[i]]-1,1);
}
}
sort(ans+1,ans+ans[0]+1);
fo(i,1,ans[0]){
write(ans[i]);
if(i<ans[0])P(' ');
}
return 0;
}