[SDOI2011]染色

题目描述

输入格式

不只有线段树外的节点需要合并,线段树内相邻节点,也要判合并

#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)

using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=100005; 
int n,m,tot,ans,k=1;
int size[maxn],son[maxn],top[maxn],fa[maxn],deep[maxn];
int rev[maxn],seg[maxn],col[maxn];
int hd[maxn];

struct node{
    int to,nt;
}e[maxn<<1]; 
inline void add(int x,int y)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k; 
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k; 
}

//-------------------------------------------------------------------------------
inline void dfs1(int x)
{
    size[x]=1;
    deep[x]=deep[fa[x]]+1;
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(v==fa[x])continue;
        fa[v]=x;
        dfs1(v);
        size[x]+=size[v];
        if(size[v]>size[son[x]])
            son[x]=v;
    }
    
}

inline void dfs2(int x,int ftop)
{
    top[x]=ftop;
    seg[x]=++tot;
    rev[tot]=x;
    if(son[x])
        dfs2(son[x],ftop);
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(!top[v])
            dfs2(v,v);
    }
}
//----------------------------------------------------------------------------------
#define lson rt<<1
#define rson rt<<1|1
int sum[maxn<<2],lc[maxn<<2],rc[maxn<<2],lazy[maxn<<2];

inline void pushup(int rt)
{
    lc[rt]=lc[lson];
    rc[rt]=rc[rson];
    sum[rt]=sum[lson]+sum[rson]-(rc[lson]==lc[rson]);
}

inline void pushdown(int rt)
{
    lazy[lson]=lazy[rson]=1;
    sum[lson]=1;sum[rson]=1;
    lc[lson]=rc[lson]=lc[rt];
    lc[rson]=rc[rson]=rc[rt];
    lazy[rt]=0;
}

inline void build(int rt,int l,int r)
{
    if(l==r)
    {
        lc[rt]=rc[rt]=col[rev[l]];
        sum[rt]=1;
        re ;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(rt);
}

inline void addd(int rt,int l,int r,int x,int y,int z)
{
    if(x<=l&&r<=y)
    {
        sum[rt]=1;
        lazy[rt]=1;
        lc[rt]=rc[rt]=z;
        re ;
    }
    if(lazy[rt])pushdown(rt);
    int mid=(l+r)>>1;
    if(x<=mid)addd(lson,l,mid,x,y,z);
    if(y>mid)addd(rson,mid+1,r,x,y,z);
    pushup(rt);
}


struct qwq{
    int l_col,r_col;
};
inline qwq query(int rt,int l,int r,int x,int y)
{
    if(x<=l&&r<=y)
    {
        ans+=sum[rt];
        re (qwq){lc[rt],rc[rt]};
    }
    int mid=(l+r)>>1;
    if(lazy[rt])pushdown(rt);
    if(y<=mid)re query(lson,l,mid,x,y);
    if(mid<x) re query(rson,mid+1,r,x,y);
    else 
    {
        qwq v1=query(lson,l,mid,x,y);
        qwq v2=query(rson,mid+1,r,x,y);
        
        if(v1.r_col==v2.l_col)--ans;
        
        re (qwq){v1.l_col,v2.r_col};
    }
}


int main()
{
//    freopen("in.txt","r",stdin);
    
    int x,y,z;
    rd(n),rd(m);
    inc(i,1,n)
    rd(col[i]);
    
    inc(i,2,n)
    {
        rd(x),rd(y);
        add(x,y);
    }
    
    dfs1(1);
    dfs2(1,1);
    build(1,1,n);
    
    
    int cnt=0;
    char ss[10];
    inc(i,1,m)
    {
        scanf("%s",ss);
        rd(x),rd(y);
        if(ss[0]=='Q')
        {
            ++cnt;
            ans=0;
        
            int lastx=-1,lasty=-1;    
              while(top[x]!=top[y])
              {
                  if(deep[top[x]]<deep[top[y]])
                  {
                      swap(x,y);
                      swap(lastx,lasty);
                }
                
            qwq    v1=query(1,1,n,seg[top[x]],seg[x]);
                ans-=(lastx==v1.r_col);
                lastx=v1.l_col;
                x=fa[top[x]];
            }
            
            if(deep[x]>deep[y])
            {
                swap(x,y);
                swap(lastx,lasty);
            }
            
            qwq v1=query(1,1,n,seg[x],seg[y]);
            ans=ans-(lastx==v1.l_col)-(lasty==v1.r_col);
            printf("%d
",ans);
        }
        else
        {
             rd(z);
             while(top[x]!=top[y])
             {
                 if(deep[top[x]]<deep[top[y]])
                    swap(x,y);
                addd(1,1,n,seg[top[x]],seg[x],z);
                x=fa[top[x]];
            }
            if(deep[x]>deep[y])swap(x,y);
            addd(1,1,n,seg[x],seg[y],z);
        }
    }
    re 0;
}
原文地址:https://www.cnblogs.com/lsyyy/p/11400291.html