JZOJ 5438. 【NOIP2017提高A组集训10.31】Tree

来源:互联网 发布:mac能用qq旋风吗 编辑:程序博客网 时间:2024/06/05 18:50

题目

这里写图片描述
样例输入
这里写图片描述

题解

由于确定了一条边的父子关系,所以当父亲和儿子的颜色不一致时,直接对儿子进行反色操作。因为父亲进步进行反色操作,父与子的颜色还是不一致。
然而我蠢。
我维护了基于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;}
阅读全文
1 0
原创粉丝点击