[传送门]

树链剖分就行了,注意线段树上颜色的合并

Code

#include <cstdio>
#include <algorithm>
#define N 100010
#define MID int mid=(l+r)>>1,ls=id<<1,rs=id<<1|1
#define len (r-l+1)
using namespace std; struct tree{
int lc,rc,sum,tag;
tree(){lc=rc=tag=-1;sum=0;}
friend tree operator +(tree a,tree b){
if(a.lc==-1) return b;
if(b.lc==-1) return a;
tree c;
c.lc=a.lc,c.rc=b.rc;
c.sum=a.sum+b.sum-(a.rc==b.lc?1:0);
return c;
}
}T[N*4];
struct info{int to,nex;}e[N*2];
int n,m,tot,head[N],cnt,A[N];
int tid[N],dep[N],son[N],fa[N],sz[N],tp[N],tw[N]; inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
} inline void Link(int u,int v){
e[++tot].nex=head[u];head[u]=tot;e[tot].to=v;
} void dfs(int u,int pre){
sz[u]=1;
for(int i=head[u],mx=0;i;i=e[i].nex){
int v=e[i].to;
if(v==pre) continue;
fa[v]=u;
dep[v]=dep[u]+1;
dfs(v,u);
sz[u]+=sz[v];
if(sz[v]>mx){son[u]=v;mx=sz[v];}
}
} void dddfs(int u,int top){
tp[u]=top;
tid[u]=++cnt;
tw[cnt]=A[u];
if(!son[u]) return; dddfs(son[u],top);
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dddfs(v,v);
}
} void build(int l,int r,int id){
if(l==r){T[id].sum=1;T[id].lc=T[id].rc=tw[l];return;}
MID;
build(l,mid,ls);
build(mid+1,r,rs);
T[id]=T[ls]+T[rs];
} void Init(){
n=read(),m=read();
for(int i=1;i<=n;A[i++]=read());
for(int i=1;i<n;++i){
int u=read(),v=read();
Link(u,v),Link(v,u);
}
dfs(1,0);
dddfs(1,1);
build(1,n,1);
} inline void pushdown(int l,int r,int id){
int &tmp=T[id].tag;
if(tmp==-1) return;
MID;
T[ls].lc=T[ls].rc=T[rs].lc=T[rs].rc=tmp;
T[ls].sum=T[rs].sum=1;
T[ls].tag=T[rs].tag=tmp;
tmp=-1;
} int query(int l,int r,int id,int L,int R){
if(L<=l&&r<=R) return T[id].sum;
pushdown(l,r,id);
MID;
int res=0;
if(R<=mid) res+=query(l,mid,ls,L,R);
else if(L>mid) res+=query(mid+1,r,rs,L,R);
else res+=query(l,mid,ls,L,R),res+=query(mid+1,r,rs,L,R),res-=(T[ls].rc==T[rs].lc)?1:0;
return res;
} int qDot(int l,int r,int id,int x){
if(l==r&&l==x) return T[id].lc;
pushdown(l,r,id);
MID;
if(x<=mid) return qDot(l,mid,ls,x);
else return qDot(mid+1,r,rs,x);
} inline int qRange(int u,int v){
int res=0;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
res+=query(1,n,1,tid[tp[u]],tid[u]);
int x=qDot(1,n,1,tid[tp[u]]),y=qDot(1,n,1,tid[fa[tp[u]]]);
if(x==y) --res;
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res+=query(1,n,1,tid[u],tid[v]);
return res;
} void update(int l,int r,int id,int L,int R,int x){
if(L<=l&&r<=R){
T[id].sum=1;
T[id].lc=T[id].rc=T[id].tag=x;
return;
}
pushdown(l,r,id);
MID;
if(L<=mid) update(l,mid,ls,L,R,x);
if(R>mid) update(mid+1,r,rs,L,R,x);
T[id]=T[ls]+T[rs];
} void updRange(int u,int v,int x){
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
update(1,n,1,tid[tp[u]],tid[u],x);
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
update(1,n,1,tid[u],tid[v],x);
} inline void solve(){
char ch;
while(m--){
for(ch=getchar();ch!='C'&&ch!='Q';ch=getchar());
if(ch=='Q'){
int u=read(),v=read();
printf("%d\n",qRange(u,v));
}else{
int u=read(),v=read(),x=read();
updRange(u,v,x);
}
}
} int main(){Init();solve();}

[BZOJ2243][SDOI2011]染色(树链剖分)的更多相关文章

  1. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  2. BZOJ2243[SDOI2011]染色——树链剖分+线段树

    题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  5. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

  6. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  7. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  8. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  9. BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

    2243: [SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数 ...

  10. 2243: [SDOI2011]染色(树链剖分+线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 8400  Solved: 3150[Submit][Status ...

随机推荐

  1. (一)JavaScript之[数据类型]与[对象]

    1].数据类型字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null).未定义 (Undefined). //极大或极小的数字可以 ...

  2. 【起航计划 008】2015 起航计划 Android APIDemo的魔鬼步伐 07 App->Activity->Persistent State 保存状态 SharedPreferences onPause onResume

    Android 提供了多种存储数据的方法,其中最简单的是使用Shared Preferences. Shared Preferences 可以存储 Key/value 对,Shared Prefere ...

  3. python socket练习

    服务器端 #服务器端 import socket server = socket.socket() server.bind(('localhost',6969))#绑定要监听的端口 server.li ...

  4. 监控系统-nagios

    https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/ install yum -y install nagios-4 ...

  5. C#实现屏幕指定区域截屏

    //string Opath = @"C:/Picture";            //if (Opath.Substring(Opath.Length - 1, 1) != @ ...

  6. 类型信息(RTTI和反射)——反射

    运行时类型信息可以让你在程序运行时发现和使用类型信息. 在Java中运行时识别对象和类的信息有两种方式:传统的RTTI,以及反射.下面就来说说反射. 重点说说通过反射获取方法以及调用方法,即类方法提取 ...

  7. Dijkstra单源最短路径,POJ(2387)

    题目链接:http://poj.org/problem?id=2387 Dijkstra算法: //求某一点(源点)到另一点的最短路,算法其实也和源点到所有点的时间复杂度一样,O(n^2); 图G(V ...

  8. create-react-app项目使用假数据

    做新项目的时候,前端每次要等后端接口准备好再开始,就会延期,等后端接口准备好了,前端这边的项目又会相互紧张,如果前端跟后端同时进行,前期将框架,基础做好,定好接口文档,前端在后端没准备好接口的时候使用 ...

  9. ES6 初体验 —— gulp+Babel 搭建ES6环境

    ES6已经火了好久了,我却一直没有在项目中尝试过使用ES6写代码,只是写过几个Demo,在大型项目中使用ES6这件事,我一直不太敢做.最近公司要求做一个小的H5活动专题,我想不如就在这个小项目中使用E ...

  10. 【Java-Regex】该用正则表达式却偷懒使用 indexOf 引起的BUG

    留着等下写. 背景 Excel列内容,无法获取全部格式,但我们有最终的准确格式. 用准确格式去严格匹配,而不是盲人摸象. 不符合就置为空,符合就.