做题记录整理图论/树3 P2486 [SDOI2011]染色(2022/10/17)

P2486 [SDOI2011]染色

首先一眼树剖(然后就不会了)

https://www.luogu.com.cn/blog/olyjxhy1314/solution-p2486

#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(int i=a;i<=b;i++)
#define ls q<<1
#define rs q<<1|1
using namespace std;
int n,m,ji1,ji2,lc,rc,col[1000002];
char ch;

struct node{
    int to,nex; 
}e[1000002<<1];
int hd[1000002],cnt=2;
 void ru(int u,int v) 
 {
    e[cnt].to=v;
	e[cnt].nex=hd[u];
    hd[u]=cnt++;
}

int jl,fa[1000002],id[1000002],rid[1000002],siz[1000002],dep[1000002],son[1000002],top[1000002];
void dfs1(int u,int fat) 
{
    fa[u]=fat,dep[u]=dep[fat]+1,siz[u]=1;
    for(int v,i=hd[u]; i; i=e[i].nex)
	 {
        v=e[i].to;
        if(v==fat) continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]) son[u]=v;
    }
}	
void dfs2(int u,int tp) 
{
    top[u]=tp,id[u]=++jl,rid[jl]=u;
    if(!son[u]) return;
    dfs2(son[u],tp);
    for(int v,i=hd[u]; i; i=e[i].nex) 
	{
        v=e[i].to;
        if(v==son[u]||v==fa[u]) continue;
        dfs2(v,v);
    }
} 


struct node2{
     int l;
	 int r;
	 int lc;
	 int rc;
	 int c;
	 int v;  
}s[1000002<<4];
 void pushup(int q) 
 {
    s[q].v=s[ls].v+s[rs].v;
    if(s[ls].rc==s[rs].lc) --s[q].v;
    s[q].lc=s[ls].lc;
    s[q].rc=s[rs].rc;
}
 void pushcol(int q,int col) 
 {
    s[q].lc=s[q].rc=col;
    s[q].v=1,s[q].c=col;
}
 void pushdown(int q) 
 {
    if(s[q].c) {
        if(ls) pushcol(ls,s[q].c);
        if(rs) pushcol(rs,s[q].c);
        s[q].c=0;
    }
}
void build(int q,int l,int r) 
{
    s[q].l=l,s[q].r=r;
    if(l==r)
	 {
        s[q].lc=s[q].rc=col[rid[l]];
        s[q].v=1;
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(q);
}
void xg(int q,int L,int R,int x)
{
    int l=s[q].l,r=s[q].r;
    if(L<=l&&r<=R)
	 {
        pushcol(q,x);
        return;
    }
    pushdown(q);
    int mid=l+r>>1;
    if(L<=mid) xg(ls,L,R,x);
    if(R>mid) xg(rs,L,R,x);
    pushup(q);
}
int cx(int q,int L,int R) 
{
    int l=s[q].l,r=s[q].r;	
    if(L<=l&&r<=R) 
	{
    	if(l==L) lc=s[q].lc;
    	if(r==R) rc=s[q].rc;      
    	return s[q].v;  
    }
    pushdown(q);
    int mid=l+r>>1;
    if(R<=mid) return cx(ls,L,R);
    if(L>mid)  return cx(rs,L,R);
    int ret=cx(ls,L,R)+cx(rs,L,R);
    if(s[ls].rc==s[rs].lc) --ret;
    return ret; 
}
 void add(int u,int v,int c) 
 {
    while(top[u]!=top[v]) 
	{
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        xg(1,id[top[u]],id[u],c);
        u=fa[top[u]];
    }
    if(id[u]>id[v]) swap(u,v);
    xg(1,id[u],id[v],c);
}
 int ask(int u,int v) 
 {
    int ret=0;
    ji1=ji2=0;
    while(top[u]!=top[v]) 
	{
        if(dep[top[u]]<dep[top[v]]) swap(u,v),swap(ji1,ji2);		
        ret+=cx(1,id[top[u]],id[u]);
        if(rc==ji1) --ret;
        ji1=lc,u=fa[top[u]];
    }
    if(id[u]>id[v]) swap(u,v),swap(ji1,ji2);
    ret+=cx(1,id[u],id[v]);
    if(lc==ji1) --ret;
    if(rc==ji2) --ret; 
    return ret;
}

int main() 
{
    cin>>n>>m;
    for1(i,1,n) cin>>col[i];
    int u,v;
    for1(i,1,n-1) 
	{
        cin>>u>>v;
		ru(u,v);
		ru(v,u);
    }
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    int a,b,c;
    for1(i,1,m)
	{
        ch=getchar();
        while(ch!='C'&&ch!='Q') ch=getchar();
        if(ch=='C')
		 {
            cin>>a>>b>>c;
            add(a,b,c);
        }
        if(ch=='Q')
		 {
            cin>>a>>b;
            printf("%d\n",ask(a,b));
        }
    }
    return 0;
}
posted @ 2022-10-17 17:06  yyx525jia  阅读(24)  评论(0)    收藏  举报