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. EntityFramework Core解决并发详解

    前言 对过年已经无感,不过还是有很多闲暇时间来学学东西,这一点是极好的,好了,本节我们来讲讲EntityFramewoek Core中的并发问题. 话题(EntityFramework Core并发) ...

  2. 【LeetCode题解】二叉树的遍历

    我准备开始一个新系列[LeetCode题解],用来记录刷LeetCode题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有 ...

  3. iOS 容器控制器 (Container View Controller)

    iOS 容器控制器 (Container View Controller) 一个控制器包含其他一个或多个控制器,前者为容器控制器 (Container View Controller),后者为子控制器 ...

  4. 【福利大放送】不止是Android,Github超高影响力开源大放送,学习开发必备教科书

    一.写在前面 最近项目重构,时间贼多,也没什么时间更新博客,个人的开源项目也是多时没有更新了:github地址,然而没有更新不代表我不在乎,后面一有空还是会继续提交的. 还是来冒个泡,给大家献上一些福 ...

  5. android Android性能优化之如何避免Overdraw

    什么是Overdraw? Overdraw就是过度绘制   怎么来消灭overdraw呢?总的原则就是:尽量避免重叠不可见元素的绘制,基于这个原则,我们大概可以想出以下几招: 第一招:合理选择控件容器 ...

  6. 在Ubuntu12.0至14.04版本之间用Apache搭建网站运行环境

    为了顺利安装各种软件,先更新下系统. apt-get update 安装Apache服务 apt-get install apache2 -y 安装php apt-get install php5 - ...

  7. sessionstorage,localstorage和cookie之间的区别以及各自的用法

    由于年前辞了自己的工作,年后又开始重新找工作,参加了好几次面试,居然都遇到了同样的面试题:sessionstorage,localstorage和cookie之间的是区别? 当然,在面试的时候答的也不 ...

  8. 腾讯X5内核使用 Android WebView 的一些小问题

    大家好,我是博客小白,第一篇文章,文笔不好,务喷,希望能给各位提供点帮助 公司做个商城,然后我就简单的做个启动引导页,然后用个原生WebView套一下,加个加载动画,解决下第三方登录支付的返回问题,这 ...

  9. Spring MVC 的环境搭建和入门小程序

    1.1.下载spring框架包. 1.1.1百度搜索Spring Framework. 进入spring官网,在网页右边选择想要下载的版本.如图 1.1.2进入页面按Ctrl+F搜索Distribut ...

  10. Java模拟新浪微博登陆抓取数据

    前言:  兄弟们来了来了,最近有人在问如何模拟新浪微博登陆抓取数据,我听后默默地抽了一口老烟,暗暗的对自己说,老汉是时候该你出场了,所以今天有时间就整理整理,浅谈一二. 首先:  要想登陆新浪微博需要 ...