题意:

给定一棵有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. AutoLayout处理UITableView动态高度

    我们经常会遇到UITableViewCell的高度要跟随内容而调整,在未引入AutoLayout之前,我们使用以下方法计算Label高度,然后heightForRowAtIndexPath中返回计算的 ...

  2. Ubuntu16.04+GTX1080配置TensorFlow并实现图像风格转换

    1. TensorFlow TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,表达了高层次的机器学习计算,大幅简化了第一代系统,并且具备更好的灵活性和可延展性. Te ...

  3. Linux常用快捷键以及如何查看命令帮助

    1.1    Linux系统快速操作常用快捷键 快捷键名称 快捷作用 Ctrl + a 将光标移至行首 Ctrl + e 将光标移至行尾 Ctrl + u 前提光标在行尾,则清除当前行所有的内容(有空 ...

  4. django开发之model篇-Field类型讲解

    今天介绍一下django开发中,定义模型时用到的相关字段类型和字段选项. 先说说常用的字段类型:1) AutoField: 自增字段类型,当自定义自增类型的id时,可以使用此类型:2) BigAuto ...

  5. jQuery 淡入淡出有png图的时候 ie8下有黑色边框

    jQuery fadeTo 时ie8 png图片有黑色边框 往带有png图的样式里加 filter:progid:DXImageTransform.Microsoft.AlphaImageLoader ...

  6. 22.Yii2.0框架多表关联一对一查询之hasOne

    思路: 通过文章查它对应的分类信息 一对一的关系 控制器里 //一对一关联查询 public function actionRelatesone() { //方法一,hasOne() 用查一条文章的结 ...

  7. GoF23种设计模式之结构型模式之代理模式

    一.概述 为其他对象提供一种代理以控制对这个对象的访问. 二.适用性 1.远程代理(RemoteProxy):为一个对象在不同的地址空间土工局部代表. 2.虚代理(VirtualProxy):根据需要 ...

  8. python中文件操作的六种模式及对文件某一行进行修改的方法

    一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...

  9. Java-basic-6-方法

    命令行参数的使用 public class test { public static void main(String args[]) { for(int i = 0; i < args.len ...

  10. POJ:1330-Nearest Common Ancestors(LCA在线、离线、优化算法)

    传送门:http://poj.org/problem?id=1330 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K ...