2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 3113  Solved: 1204
[Submit][Status][Discuss]

Description

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

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

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

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

Input

第一行包含2个整数n和m,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

下面 行每行描述一个操作:

“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<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

Source

第一轮day1

题解:又是一个树链剖分= =,其实越来越感觉链剖更多的是一种思想,通过树链剖分将树上的区间维护问题转化为线段树维护问题,比如这题就可以转化为一个区间覆盖与区间段数查询问题,关键在于合并区间信息

然后说些要注意的地方:1.在求出LCA再求出两条分链信息之后,记得要倒转过来,否则合并将得不到想要的(注意:区间合并具有方向性)

2.事实上,求出两条支链后不需要把交点,也就是LCA点非要排除掉(HansBug:事实上保留也根本不影响结果,想想为什么= =)

(PS:发现链剖问题每次最终坑我的都是线段树部分啊有木有TT)

 /**************************************************************
Problem:
User: HansBug
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ type
color=record
lef,rig,mid:longint;
end;
point=^node;
node=record
g:longint;
next:point;
end;
var
d:array[..] of color;
a:array[..] of point;
e,len,son,num,anum,top,siz,f:array[..] of longint;
c:array[..,..] of longint;
i,j,k,l,m,n,tot,root:longint;ch:char;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
function max(x,y:longint):longint;
begin
if x>y then max:=x else max:=y;
end;
procedure swap(var x,y:longint);
var z:longint;
begin
z:=x;x:=y;y:=z;
end;
function turn(x:color):color;
begin
swap(x.lef,x.rig);
exit(x);
end;
function pure(x:color):boolean;
begin
exit((x.lef=x.rig) and (x.mid=));
end;
function number(x:color):longint;
begin
if x.mid> then exit(x.mid+) else
if x.lef=x.rig then exit() else exit();
end;
function empty(x:color):boolean;
begin
exit((x.lef=-) and (x.rig=-) and (x.mid=))
end;
function getcolor(x,y,z:longint):color;
var p:color;
begin
p.lef:=x;p.rig:=y;p.mid:=z;
exit(p);
end;
function merge(x,y:color):color;
var z:color;
begin
if empty(x) then exit(y);
if empty(y) then exit(x);
z:=getcolor(x.lef,y.rig,);
if not(pure(x)) then inc(z.mid,x.mid+);
if not(pure(y)) then inc(z.mid,y.mid+);
if (z.mid>) and (x.rig=y.lef) then dec(z.mid);
exit(z);
end;
procedure add(x,y:longint);
var p:point;
begin
new(p);p^.g:=y;p^.next:=a[x];a[x]:=p;
end;
procedure dfs(y,x:longint);
var p:point;
begin
len[x]:=len[y]+;
c[,x]:=y;son[x]:=;
siz[x]:=;p:=a[x];
while p<>nil do
begin
if p^.g<>y then
begin
dfs(x,p^.g);
if (son[x]=) or (siz[p^.g]>siz[son[x]]) then son[x]:=p^.g;
inc(siz[x],siz[p^.g]);
end;
p:=p^.next;
end;
end;
procedure dfs2(y,x,z:longint);
var p:point;
begin
top[x]:=z;inc(tot);num[x]:=tot;anum[tot]:=x;
if son[x]<> then dfs2(x,son[x],z);
p:=a[x];
while p<>nil do
begin
if (p^.g<>y) and (p^.g<>son[x]) then dfs2(x,p^.g,p^.g);
p:=p^.next;
end;
end;
procedure built(z,x,y:longint);
begin
if x=y then
d[z]:=getcolor(f[anum[x]],f[anum[x]],)
else
begin
built(z*,x,(x+y) div );
built(z*+,(x+y) div +,y);
d[z]:=merge(d[z*],d[z*+]);
end;
e[z]:=-;
end;
procedure ext(z,x,y:longint);
begin
if e[z]=- then exit;
d[z]:=getcolor(e[z],e[z],);
if x<>y then
begin
e[z*]:=e[z];
e[z*+]:=e[z];
end;
e[z]:=-;
end;
function cover(z,x,y,l,r,t:longint):color;
var p1,p2:color;
begin
if l>r then if e[z]<>- then exit(getcolor(e[z],e[z],)) else exit(d[z]);
if (l=x) and (r=y) then
begin
e[z]:=t;
exit(getcolor(t,t,));
end;
ext(z,x,y);
p1:=cover(z*,x,(x+y) div ,l,min(r,(x+y) div ),t);
p2:=cover(z*+,(x+y) div +,y,max((x+y) div +,l),r,t);
d[z]:=merge(p1,p2);
exit(d[z]);
end;
function doit(z,x,y,l,r:longint):color;
var p1,p2:color;
begin
if l>r then exit(getcolor(-,-,));
if e[z]<>- then exit(getcolor(e[z],e[z],));
if (x=l) and (y=r) then exit(d[z]);
p1:=doit(z*,x,(x+y) div ,l,min(r,(x+y) div ));
p2:=doit(z*+,(x+y) div +,y,max((x+y) div +,l),r);
exit(merge(p1,p2));
end;
function getup(x,y:longint):longint;
var i:longint;
begin
i:=;
while y> do
begin
if odd(y) then x:=c[i,x];
inc(i);y:=y div ;
end;
exit(x);
end;
function getcom(x,y:longint):longint;
var i:longint;
begin
if len[x]<len[y] then swap(x,y);
x:=getup(x,len[x]-len[y]);
if x=y then exit(x);
for i:=trunc(round(ln(len[x])/ln())) downto do
if c[i,x]<>c[i,y] then
begin
x:=c[i,x];
y:=c[i,y];
end;
exit(c[,x]);
end;
procedure treecolor(x,y,t:longint);
var z,i:longint;
begin
z:=getcom(x,y);
repeat
if len[top[x]]<len[z] then i:=z else i:=top[x];
cover(,,n,num[i],num[x],t);
if i=z then break;
x:=c[,i];
until false;
repeat
if len[top[y]]<len[z] then i:=z else i:=top[y];
cover(,,n,num[i],num[y],t);
if i=z then break;
y:=c[,i];
until false;
end;
function treecount(x,y:longint):longint;
var z,i:longint;p1,p2:color;
begin
p1:=getcolor(-,-,);p2:=getcolor(-,-,);
z:=getcom(x,y);
repeat
if len[top[x]]<len[z] then i:=z else i:=top[x];
p1:=merge(p1,turn(doit(,,n,num[i],num[x])));
if i=z then break;
x:=c[,i];
until false; repeat
if len[top[y]]<len[z] then i:=z else i:=top[y];
p2:=merge(doit(,,n,num[i],num[y]),p2);
if i=z then break;
y:=c[,i];
until false; exit(number(merge(p1,p2)));
end;
begin
readln(n,m);
for i:= to n do a[i]:=nil;
for i:= to n do read(f[i]);
readln;
for i:= to n- do
begin
readln(j,k);
add(j,k);add(k,j);
end;
root:=;dfs(,root);dfs2(,root,root);
for i:= to trunc(round(ln(n)/ln()))+ do
for j:= to n do
c[i,j]:=c[i-,c[i-,j]];
built(,,n); for i:= to m do
begin
read(ch);
case ch of
'Q':begin
readln(j,k);
writeln(treecount(j,k));
end;
'C':begin
readln(j,k,l);
treecolor(j,k,l);
end;
end;
end;
readln;
end.

2243: [SDOI2011]染色的更多相关文章

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

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

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

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

  3. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

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

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

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

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

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

  6. bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)

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

  7. 2243: [SDOI2011]染色(LCT)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 10909  Solved: 4216[Submit][Statu ...

  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路径上的颜色段数 ...

随机推荐

  1. PHP上传图片重命名6种方案

    一. 适用场景:无法使用从数据库中返回的自增长数字,给上传图片重命名.这是图片或文件上传的流程决定的.一般图片上传处理过程是,先上传图片到服务器,重命名之后,插入到数据库.也就是说,在数据库中非常容易 ...

  2. 第一篇:CUDA 6.0 安装及配置( WIN7 64位 / 英伟达G卡 / VS2010 )

    前言 本文讲解如何在VS 2010开发平台中搭建CUDA开发环境. 当前配置: 系统:WIN7 64位 开发平台:VS 2010 显卡:英伟达G卡 CUDA版本:6.0 若配置不同,请谨慎参考本文. ...

  3. java中的静态代理和动态代理,入门整理

    静态代理和动态代理主要解决的问题是:在直接访问对象时带来的问题,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 ...

  4. HDU5505

    GT and numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构

    http://www.infoq.com/interviews/Technology-Influences-DDD# 要实现DDD(domain drive  design 领域驱动设计)原始意图,必 ...

  6. 解决使用Idea/Eclipse编写Hadoop程序包依赖问题

    解决使用Idea/Eclipse编写Hadoop程序包依赖问题 解决包依赖的一种简单粗暴方法就是, 把下载下来的Hadoop压缩包解压, 搜索里面所有的额jar包文件,然后复制到一个目录,在使用Ide ...

  7. duilib 绘制IP控件

    在使用duilib时,发现本来的库并没有提供IP控件,如是自己想到绘制IP控件,控件的绘制不难,首先赋值UIEdit的两个文件,命名为UIIPEdit,更改完成后,便可以进行修改绘制IP控件. 绘制难 ...

  8. ArcGIS Pro 简明教程(2)基础操作和简单制图

    ArcGIS Pro 简明教程(2)基础操作和简单制图 By 李远祥 本章主要介绍ArcGIS Pro如何加载数据并进行简单的地图制作,以基本的操作为主. 上一章节介绍过,ArcGIS Pro是可以直 ...

  9. nginx : server_name localhost 和 chrome : Provisional headers are shown

    问题相关问题现象:解决思路解决方案总结 问题相关 nginx : server_name localhost chrome : Provisional headers are shown 问题现象: ...

  10. 读书笔记 effective c++ Item 12 拷贝对象的所有部分

    1.默认构造函数介绍 在设计良好的面向对象系统中,会将对象的内部进行封装,只有两个函数可以拷贝对象:这两个函数分别叫做拷贝构造函数和拷贝赋值运算符.我们把这两个函数统一叫做拷贝函数.从Item5中,我 ...