NOI AC#62 color(树上操作)

传送门

其实这道题不用二分去找分界点也能过的说。

所以也用不着树链剖分了。

只要每次改到当前颜色与原来是一样的停止即可。

然后代码贼简单。

#include<bits/stdc++.h>
#define LL long long
#define re register
#define INF 2100000000
#define N 100003
#define mod 1000000007
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
struct EDGE{
    int nextt,to;
}w[N*2];
struct point{
    int col,white,black,gray;
}p[N];
int head[N],tot=0;
int fa[N],son[N],siz[N];
int ans[5];
void add(int a,int b)
{
    tot++;
    w[tot].nextt=head[a];
    w[tot].to=b;
    head[a]=tot;
}
int n,m;
void dfs(int x)
{
    siz[x]=0;
    for(int i=head[x];i;i=w[i].nextt)
    {
        int v=w[i].to;
        if(v==fa[x])continue;
        dfs(v);
        siz[x]++;
        if(p[v].col==1)p[x].black++;
        else if(p[v].col==0)p[x].white++;
        else p[x].gray++;
    }
    if(!son[x])
    {
        ans[p[x].col]++;
        return;
    }
    if(p[x].black==siz[x])p[x].col=1,ans[1]++;
    else if(p[x].white==siz[x])p[x].col=0,ans[0]++;
    else p[x].col=2,ans[2]++;
}
void update(int x,int now,int before)
{
    if(x==0)return;
    if(before==1)p[x].black--;
    else if(before==0)p[x].white--;
    else p[x].gray--;
    if(now==1)p[x].black++;
    else if(now==0)p[x].white++;
    else p[x].gray++;
    int tmp=p[x].col;
    if(p[x].black==siz[x])p[x].col=1;
    else if(p[x].white==siz[x])p[x].col=0;
    else p[x].col=2;
    if(p[x].col==tmp)return;
    ans[tmp]--;ans[p[x].col]++;
    update(fa[x],p[x].col,tmp);
}
int main()
{
    int rt;
    n=read();m=read();
    for(int i=1;i<=n;++i)
    {
        fa[i]=read();
        if(fa[i]==0)rt=i;
        add(fa[i],i);add(i,fa[i]);
        son[fa[i]]++;
    }
    for(int i=1;i<=n;++i)p[i].col=read();
    dfs(rt);
    for(int i=1;i<=m;++i)
    {
        int x=read();
        int col=p[x].col;
        ans[col]--;ans[col^1]++;
        p[x].col=col^1;
        update(fa[x],col^1,col);
        printf("%d %d %d
",ans[1],ans[0],ans[2]);
    }
}
View Code
原文地址:https://www.cnblogs.com/yyys-/p/11802020.html