[bzoj2243][SDOI2011]染色
Description
给定一棵有$n$个节点的无根树和$m$个操作,操作有$2$类:
1.将节点$a$到节点$b$路径上所有点都染成颜色$c$;
2.询问节点$a$到节点$b$路径上的颜色段数量(连续相同颜色被认为是同一段),如$"112221"$由$3$段组成:$"11","222"和"1"$.
请你写一个程序依次完成这$m$个操作.
Input
第一行包含$2$个整数$n$和$m$,分别表示节点数和操作数.
第二行包含$n$个正整数表示$n$个节点的初始颜色.
下面$n-1$行每行包含两个整数$x$和$y$,表示$x$和$y$之间有一条无向边.
下面$m$行每行描述一个操作:
$”C\;a\;b\;c”$表示这是一个染色操作,把节点$a$到节点$b$路径上所有点(包括$a$和$b$)都染成颜色$c$;
$”Q\;a\;b”$表示这是一个询问操作,询问节点$a$到节点$b$(包括$a$和$b$)路径上的颜色段数量.
Output
对于每个询问操作,输出一行答案.
Sample Input
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
3
1
2
HINT
$N,M\;\leq\;10^5,c\;\in\;z,c\;\in\;[0, 10^9]$.
Solution
树链剖分+线段树.
每次上移的时候判断相邻两段端点是否同色即可.
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 300005
using namespace std;
struct linetree{
int l,r,lc,rc,cnt;
}lt[M];
struct graph{
int nxt,to;
}e[M];
char c[2];
int g[N],a[N],w[N],n,m,u,v,k,l,cnt;
int f[N],p[N],dep[N],siz[N],son[N],top[N];
inline void addedge(int x,int y){
e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
}
inline void dfs1(int u){
int m=0;siz[u]=1;
for(int i=g[u];i;i=e[i].nxt)
if(!dep[e[i].to]){
f[e[i].to]=u;
dep[e[i].to]=dep[u]+1;
dfs1(e[i].to);
siz[u]+=siz[e[i].to];
if(siz[e[i].to]>m){
son[u]=e[i].to;
m=siz[e[i].to];
}
}
}
inline void dfs2(int u,int tp){
top[u]=tp;p[u]=++cnt;w[cnt]=a[u];
if(son[u]) dfs2(son[u],tp);
for(int i=g[u];i;i=e[i].nxt)
if(f[u]!=e[i].to&&e[i].to!=son[u])
dfs2(e[i].to,e[i].to);
}
inline void build(int u,int l,int r){
lt[u].l=l;lt[u].r=r;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
build(lef,l,mid);build(rig,mid+1,r);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
else{
lt[u].cnt=1;lt[u].lc=lt[u].rc=w[lt[u].l];
}
}
inline void cover(int u,int l,int r,int k){
if(lt[u].l>=l&<[u].r<=r){
lt[u].lc=lt[u].rc=k;lt[u].cnt=1;
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[lef].rc=lt[rig].lc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) cover(lef,l,r,k);
if(r>mid) cover(rig,l,r,k);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
}
inline int ask(int u,int l,int r){
if(lt[u].l>=l&<[u].r<=r)
return lt[u].cnt;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1,ret=0;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) ret+=ask(lef,l,r);
if(r>mid) ret+=ask(rig,l,r);
if(l<=mid&&r>mid&<[lef].rc==lt[rig].lc) --ret;
return ret;
}
}
inline int col(int u,int x){
if(lt[u].l==x) return lt[u].lc;
if(lt[u].r==x) return lt[u].rc;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(x<=mid) return col(lef,x);
return col(rig,x);
}
}
inline void cov(int x,int y,int k){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
cover(1,p[top[x]],p[x],k);
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
cover(1,p[x],p[y],k);
}
inline int q(int x,int y){
int ret=0,t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
ret+=ask(1,p[top[x]],p[x]);
if(col(1,p[top[x]])==col(1,p[f[top[x]]])) --ret;
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
ret+=ask(1,p[x],p[y]);
return ret;
}
inline int lca(int x,int y){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
return x;
}
inline void Aireen(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1,x,y;i<n;++i){
scanf("%d%d",&x,&y);
addedge(x,y);addedge(y,x);
}
dep[1]=1;dfs1(1);
cnt=0;dfs2(1,1);
build(1,1,n);
while(m--){
scanf("%s%d%d",c,&u,&v);
if(c[0]=='C'){
scanf("%d",&k);cov(u,v,k);
}
else{
l=lca(u,v);
printf("%d\n",q(u,v));
}
}
}
int main(){
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}
[bzoj2243][SDOI2011]染色的更多相关文章
- BZOJ2243 SDOI2011 染色 【树链剖分】
BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ2243[SDOI2011]染色——树链剖分+线段树
题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...
- [BZOJ2243][SDOI2011]染色 解题报告|树链剖分
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ2243: [SDOI2011]染色(树链剖分/LCT)
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...
- bzoj2243: [SDOI2011]染色--线段树+树链剖分
此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加 ...
- BZOJ2243——[SDOI2011]染色
1.题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段 2.分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建 ...
- bzoj2243 sdoi2011 染色 paint
明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang #include<iostream> #include<cstring> # ...
随机推荐
- IE11下不能引入外部css的解决方法
原: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...
- redis-cache中的callback
这个是mybatis/redis-cache中关键类 RedisCache 的源码 /** * Copyright 2015 the original author or authors. * * ...
- JVM的堆(heap)、栈(stack)和方法区(method)
JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...
- [转]Class 'Think\Log' not found
转自:http://www.thinkphp.cn/topic/26815.html 解决偶尔出现 Class 'Think\Log' not found 的奇葩问题(并非每次必现,偶尔删除缓存可以解 ...
- 您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mysql的技巧
转载至: http://www.cnblogs.com/Imaigne/p/4153397.html 您的项目引用了最新实体框架:但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mys ...
- Camera.Parameters 参数
public class Camera.Parameters extends Object java.lang.Object ↳ android.hardware.Camera.Paramete ...
- 分布式中使用Redis实现Session共享(一)
上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...
- TRIGGER command denied to user 'root'@'LAPTOP-M7KUFN86' for table 'growtest' | Table 'MyDatabase.tmpIdentity_Invites' doesn't exist
是因为创建表的时候,用户权限不够 NaviCat for Mysql 用这个工具打开MYSQL 在用户 下找到 root@% 这个用户,双击打开 设置服务器权限,最后两个权限勾上就OK 了,需要把MY ...
- 解决Package illuminate/html is abandoned, you should avoid using it. Use laravelcollective/html instead.问题
解决步骤: 1.分析问题是因为laravel5.1不赞成使用illuminate/html而推荐使用laravelcollective/html包,所以我们利用composer命令移除illumina ...
- java并发:同步容器&并发容器
第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...