J

dfs重新排序后将 查询一下区间个数即可

tree[i][c] 表示 i-lowbit(i) 颜色为c的个数

  

#include<bits/stdc++.h>

#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define lowbit(x) x&(-x)
const int maxn=5e5+10;

using namespace std;

int tree[maxn][105],c[maxn],e[maxn],id[maxn];
int n,m,cnt=0;

vector<int>q[maxn];

void dfs(int u)
{
    id[u]=++cnt;
    int s=q[u].size();
    for(int i=0;i<s;i++)
    {
        dfs(q[u][i]);
    }
    e[u]=cnt;
}

void updata(int pos,int c,int k)
{
    for(int i=pos;i<=n;i+=lowbit(i))
        tree[i][c]+=k;
}

int query(int pos,int c)
{
    int ans=0;
    for(int i=pos;i>0;i-=lowbit(i))
        ans+=tree[i][c];
    return ans;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    for(int i=2;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        q[x].push_back(i);
    }
    dfs(1);
//    cout<<"id"<<endl;
//    for(int i=1;i<=n;i++)
//        cout<<e[i]<<" ";
//    cout<<endl;

    for(int i=1;i<=n;i++)
    {
        updata(id[i],c[i],1);
    }

    while(m--)
    {
        int cmd,pos;
        scanf("%d%d",&cmd,&pos);
        if(cmd)
        {
            updata(id[pos],c[pos],-1);
            updata(id[pos],cmd,1);
            c[pos]=cmd;
        }
        else
        {
            int ans=0;
            for(int i=1;i<=100;i++)
            {
                int t=query(e[pos],i)-query(id[pos]-1,i);
                if(t%2==1)
                    ans++;
            }
            printf("%d
",ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/minun/p/11022364.html