[传送门]

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

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. Oracle数据表比较记录差异(转)

    liuyx_know|七级 你可以参照一下Oracle的UNION [ALL], INTERSECT, MINUS操作符,至于你的问题你可以使用MINUS操作符,语句如下: SELECT * FROM ...

  2. Android中快速实现自定义字体!

    前言:我们都知道,Android中默认的字体是黑体,而大多数app也都是使用的这种字体,但我们发现,大多数app中,个别地方字体非常好看,例如app的标题栏,菜单栏等地方,那他们是怎么做到的呢?有两种 ...

  3. 爆料!如何在Visual Studio 2017上体验五星级云服务

    2017 年 3 月初,号称宇宙最强 IDE 之一的 Visual Studio 发布了最新的 2017 版本,遥想自己使用 VC++ 6.0 的当年,看着现在已然稀疏的头发,真是一入 IT 似海深, ...

  4. OpenGL学习 Our First OpenGL Program

    This shows you how to create the main window with the book’s application framework and how to render ...

  5. 【转载】#330 - Derived Classes Do Not Inherit Constructors

    A derived class inherits all of the members of a base class except for its constructors. You must de ...

  6. IOS 拦截所有push进来的子控制器

    /** * 能拦截所有push进来的子控制器 */ - (void)pushViewController:(UIViewController *)viewController animated:(BO ...

  7. git 分之合并和冲突解决

    Git 分支管理和冲突解决 创建分支 git branch 没有参数,显示本地版本库中所有的本地分支名称. 当前检出分支的前面会有星号. git branch newname 在当前检出分支上新建分支 ...

  8. CRSF在ASP.NET CORE MVC 的处理方式

    https://www.cnblogs.com/catcher1994/p/6720212.html

  9. UIView的层次调整,及子view布局模式自动布局模式(停靠模式)

    UIView*view1=[[UIView alloc]initWithFrame:CGRectMake(10,30,300,30)]; view1.backgroundColor=[UIColor ...

  10. Jmeter文件目录,功能简介

    1.Jmeter文件目录:1)bin文件: Jmeter启动:bin/jmeter.bat Jmeter日志文件:jmeter.log Linux的启动文件:Jmeter.sh Jmeter系统配置文 ...