title : [SDOI2011]染色(路径染色+色段查询)
tags : ACM,数据结构
date : 2021-11-16
author : Linno
P2486 [SDOI2011]染色
题面
给一棵树,支持两种操作:
①给定u,v,w,将u到v的路径上所有节点染成颜色w。
②给定u,v,查询u到v路径上颜色段的数量。
树链剖分+线段树
树链剖分将无根树拍平后,用线段树去做。维护每个区间的左颜色、右颜色、色段和以及tag,如果合并的时候两端颜色一致,那么ans-1。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,m,col[N];
vector<int>G[N];
void addedge(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
int sz[N],dep[N],son[N],fa[N],bel[N],dfn[N],idfn[N],idx=0;
inline void dfs1(int x){
sz[x]=1;
for(int i=0;i<G[x].size();i++){
int to=G[x][i];
if(to==fa[x]) continue;
dep[to]=dep[x]+1;
fa[to]=x;
dfs1(to);
sz[x]+=sz[to];
if(sz[son[x]]<sz[to]) son[x]=to;
}
}
inline void dfs2(int x,int tp){ //重链剖分
dfn[x]=++idx;
idfn[idx]=x;
bel[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=0;i<G[x].size();i++){
int to=G[x][i];
if(to==fa[x]||to==son[x]) continue;
dfs2(to,to);
}
}
struct Node{
int sum,l,r,lc,rc,tg,c;
}tr[N<<2];
#define lss p<<1
#define rss p<<1|1
inline void build(int p,int l,int r){
tr[p].l=l;tr[p].r=r;
if(l==r){
tr[p].sum=1;
tr[p].c=tr[p].lc=tr[p].rc=col[idfn[l]];
return;
}
int mid=(