题意:

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

思路:树上的路径染色问题可以用树剖解决。

对于线段树的某个节点我们记录以下信息:最左端颜色,最右端颜色,整段中段数,以及lazytag。

其中lazytag>=0时表示该区间要改成什么颜色,-1表示当前节点没有标记。

转换到树上做即可

BZOJ过了样例就一遍过(萎靡)

 type un=record
l,r,s,tag:longint;
end;
var t:array[..]of un;
f:array[..,..]of longint;
head,vet,next,flag,dep,fa,top,
tid,id,size,son,a:array[..]of longint;
n,m,i,j,k,x,y,z,q,tot,time:longint;
ch:string;
emp:un; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure add(a,b:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
head[a]:=tot;
end; procedure dfs1(u:longint);
var e,v,maxsize,i:longint;
begin
flag[u]:=; size[u]:=; maxsize:=; son[u]:=;
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end; e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
dep[v]:=dep[u]+;
f[v,]:=u;
fa[v]:=u;
dfs1(v);
size[u]:=size[u]+size[v];
if size[v]>maxsize then
begin
maxsize:=size[v];
son[u]:=v;
end;
end;
e:=next[e];
end;
end; procedure dfs2(u,ance:longint);
var e,v:longint;
begin
flag[u]:=; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance;
if son[u]> then dfs2(son[u],ance);
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then dfs2(v,v);
e:=next[e];
end;
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; procedure pushup(p:longint);
begin
t[p].l:=t[p<<].l; t[p].r:=t[p<<+].r;
if t[p<<].r<>t[p<<+].l then t[p].s:=t[p<<].s+t[p<<+].s
else t[p].s:=t[p<<].s+t[p<<+].s-;
end; procedure pushdown(p,l,r:longint);
var tmp:longint;
begin
tmp:=t[p].tag; t[p].tag:=-;
if (tmp=-)or(l=r) then exit;
t[p<<].s:=; t[p<<+].s:=;
t[p<<].tag:=tmp; t[p<<+].tag:=tmp;
t[p<<].l:=tmp; t[p<<].r:=tmp;
t[p<<+].l:=tmp; t[p<<+].r:=tmp;
end; procedure build(l,r,p:longint);
var mid:longint;
begin
if l=r then
begin
t[p].s:=;
t[p].tag:=-;
exit;
end;
t[p].tag:=-;
mid:=(l+r)>>;
build(l,mid,p<<);
build(mid+,r,p<<+);
end; procedure update(l,r,x,y,v,p:longint);
var mid:longint;
begin
pushdown(p,l,r);
if (l>=x)and(r<=y) then
begin
t[p].l:=v; t[p].r:=v;
t[p].s:=; t[p].tag:=v;
exit;
end;
mid:=(l+r)>>;
if x<=mid then update(l,mid,x,y,v,p<<);
if y>mid then update(mid+,r,x,y,v,p<<+);
pushup(p);
end; function query(l,r,x,y,p:longint):longint;
var mid,t1,t2:longint;
begin
pushdown(p,l,r);
if (l>=x)and(r<=y) then exit(t[p].s);
mid:=(l+r)>>;
t1:=; t2:=;
if x<=mid then t1:=query(l,mid,x,y,p<<);
if y>mid then t2:=query(mid+,r,x,y,p<<+);
if t1= then exit(t2);
if t2= then exit(t1);
query:=t1+t2;
if t[p<<].r=t[p<<+].l then dec(query);
end; function get(l,r,x,p:longint):longint;
var mid:longint;
begin
pushdown(p,l,r);
if (l=x)and(r=x) then exit(t[p].l);
mid:=(l+r)>>;
if x<=mid then exit(get(l,mid,x,p<<))
else exit(get(mid+,r,x,p<<+));
end; function ask(x,y:longint):longint;
var q:longint;
begin
q:=lca(x,y);
ask:=;
while top[x]<>top[q] do
begin
ask:=ask+query(,n,tid[top[x]],tid[x],);
if get(,n,tid[top[x]],)=get(,n,tid[fa[top[x]]],) then dec(ask);
x:=fa[top[x]];
end;
ask:=ask+query(,n,tid[q],tid[x],);
while top[y]<>top[q] do
begin
ask:=ask+query(,n,tid[top[y]],tid[y],);
if get(,n,tid[top[y]],)=get(,n,tid[fa[top[y]]],) then dec(ask);
y:=fa[top[y]];
end;
ask:=ask+query(,n,tid[q],tid[y],);
dec(ask); end; procedure solve(x,y,z:longint);
var q:longint;
begin
q:=lca(x,y);
while top[x]<>top[q] do
begin
update(,n,tid[top[x]],tid[x],z,);
x:=fa[top[x]];
end;
update(,n,tid[q],tid[x],z,);
while top[y]<>top[q] do
begin
update(,n,tid[top[y]],tid[y],z,);
y:=fa[top[y]];
end;
update(,n,tid[q],tid[y],z,);
end; begin
assign(input,'bzoj2243.in'); reset(input);
assign(output,'bzoj2243.out'); rewrite(output);
readln(n,m);
for i:= to n do read(a[i]);
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
dfs1();
fillchar(flag,sizeof(flag),);
dfs2(,);
build(,n,);
for i:= to n do update(,n,tid[i],tid[i],a[i],);
//for i:= to n do write(a[id[i]],' ');
for i:= to m do
begin
readln(ch);
x:=; y:=; z:=;
case ch[] of
'C':
begin
for k:= to length(ch) do
begin
if ch[k]=' ' then break;
x:=x*+ord(ch[k])-ord('');
end;
j:=k+;
for k:=j to length(ch) do
begin
if ch[k]=' ' then break;
y:=y*+ord(ch[k])-ord('');
end;
j:=k+;
for k:=j to length(ch) do z:=z*+ord(ch[k])-ord('');
solve(x,y,z);
end; 'Q':
begin
for k:= to length(ch) do
begin
if ch[k]=' ' then break;
x:=x*+ord(ch[k])-ord('');
end;
j:=k+;
for k:=j to length(ch) do y:=y*+ord(ch[k])-ord('');
writeln(ask(x,y));
end;
end;
end;
close(input);
close(output);
end.

【BZOJ2243】染色(树链剖分)的更多相关文章

  1. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

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

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

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

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

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

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

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

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

  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]染色 [树链剖分][线段树]

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

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

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

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

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

随机推荐

  1. javaweb基础(20)_JavaBean总结

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  2. iOS开发之MVVM在项目中的应用

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  3. 微信小程序传值取值的几种方法

    一,列表index下的取值 实现方式是:data-index="{{index}}"挖坑及e.currentTarget.dataset.index来填坑即可 1.1生成值 < ...

  4. 标准C++(4)继承

    一.继承的作用 若A类继承了B类,可以使A类获得B类中的部分成员变量和成员函数,这能使程序员在已有类的基础上重新定义新的类.继承是类的重要特性,当A类继承了B类,我们称A类为派生类或子类,B类为基类或 ...

  5. Python爬虫系列-Selenium+Chrome/PhantomJS爬取淘宝美食

    1.搜索关键字 利用Selenium驱动浏览器搜索关键字,得到查询后的商品列表 2.分析页码并翻页 得到商品页码数,模拟翻页,得到后续页面的商品列表 3.分析提取商品内容 利用PyQuery分析源码, ...

  6. Linux 文本编辑常用快捷键

    一.编辑模式 vim有三种编辑模式 1. i 进入文本编辑模式 2. esc 进入命令编辑模式 命令编辑状态下 dd删除整行 3. :进入底行模式 底行模式状态  输入q 退出 w保存  wq 保存并 ...

  7. python 数据结构与算法之排序(冒泡,选择,插入)

    目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习 ...

  8. python数据类型之列表(list)和其常用方法

    列表是python常用数据类型之一,是可变的,可由n = []创建,也可由n = list()创建,第一种方法更常用. 常用方法总结: # 创建方法 n = [] 或者 n = list() # in ...

  9. poj 1742 多重背包问题 dp算法

    题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种 思路:多重背包问题 dp[i][j]表示用前i种硬币组成j最多剩下多少个  dp=-1的表示凑不齐 dp ...

  10. Spring boot 中Spring data JPA的应用(一)

    最近一直在研究Spring Boot,今天为大家介绍下Spring Data JPA在Spring Boot中的应用,如有错误,欢迎大家指正. 先解释下什么是JPA JPA就是一个基于O/R映射的标准 ...