bzoj3531
不难想到树链剖分
这题的难点是记录的是路径上宗教相同的点
裸的想法是对每一种宗教都开一棵线段树,记录每个点的评级
但显然这样会爆空间,仔细分析一下,这些线段树内很多点压根就没用到
因此我们考虑对线段树动态开点,不难发现每次修改最多要开线段树上O(2*logn)个点,是可以接受的
然后就是打码的问题了
type node=record
po,next:longint;
end;
link=record
l,r,s,m:longint;
end; var tree:array[..*] of link;
fa,size,d,top,p,c,h,b,w:array[..] of longint;
e:array[..] of node;
len,t,i,n,q,x,y:longint;
ch:char; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure add(x,y:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
p[x]:=len;
end; procedure update(x:longint);
begin
tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s;
tree[x].m:=max(tree[tree[x].l].m,tree[tree[x].r].m);
end; procedure dfs1(x:longint);
var i,y:longint;
begin
size[x]:=;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if fa[x]<>y then
begin
d[y]:=d[x]+;
fa[y]:=x;
dfs1(y);
size[x]:=size[x]+size[y];
end;
i:=e[i].next;
end;
end; procedure dfs2(x:longint);
var i,y,q:longint;
begin
q:=;
inc(t);
c[x]:=t;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if (c[y]=) and (size[y]>size[q]) then q:=y;
i:=e[i].next;
end;
if q<> then
begin
top[q]:=top[x];
dfs2(q);
end;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if c[y]= then
begin
top[y]:=y;
dfs2(y);
end;
i:=e[i].next;
end;
end; function change(last,l,r,x,y:longint):longint;
var m,q:longint;
begin
inc(t);
if l=r then
begin
tree[t].m:=y;
tree[t].s:=y;
exit(t);
end
else begin
m:=(l+r) shr ;
q:=t;
if x<=m then
begin
tree[q].r:=tree[last].r;
last:=tree[last].l;
tree[q].l:=change(last,l,m,x,y);
end
else begin
tree[q].l:=tree[last].l;
last:=tree[last].r;
tree[q].r:=change(last,m+,r,x,y);
end;
update(q);
exit(q);
end;
end; function getmax(now,l,r,x,y:longint):longint;
var m,q:longint;
begin
if (x<=l) and (y>=r) then exit(tree[now].m)
else begin
m:=(l+r) shr ;
q:=;
if (x<=m) and (tree[now].l<>) then q:=getmax(tree[now].l,l,m,x,y);
if (y>m) and (tree[now].r<>) then q:=max(q,getmax(tree[now].r,m+,r,x,y));
exit(q);
end;
end; function getsum(now,l,r,x,y:longint):longint;
var m,q:longint;
begin
if (x<=l) and (y>=r) then exit(tree[now].s)
else begin
m:=(l+r) shr ;
q:=;
if (x<=m) and (tree[now].l<>) then q:=q+getsum(tree[now].l,l,m,x,y);
if (y>m) and (tree[now].r<>) then q:=q+getsum(tree[now].r,m+,r,x,y);
exit(q);
end;
end; function maxx(x,y:longint):longint;
var f1,f2,re:longint;
begin
maxx:=;
re:=b[x];
f1:=top[x];
f2:=top[y];
while f1<>f2 do
begin
if d[f1]>=d[f2] then
begin
maxx:=max(maxx,getmax(h[re],,n,c[f1],c[x]));
x:=fa[f1];
end
else begin
maxx:=max(maxx,getmax(h[re],,n,c[f2],c[y]));
y:=fa[f2];
end;
f1:=top[x];
f2:=top[y];
end;
if c[x]>c[y] then swap(x,y);
maxx:=max(maxx,getmax(h[re],,n,c[x],c[y]));
end; function ask(x,y:longint):longint;
var f1,f2,re:longint;
begin
ask:=;
re:=b[x];
f1:=top[x];
f2:=top[y];
while f1<>f2 do
begin
if d[f1]>=d[f2] then
begin
ask:=ask+getsum(h[re],,n,c[f1],c[x]);
x:=fa[f1];
end
else begin
ask:=ask+getsum(h[re],,n,c[f2],c[y]);
y:=fa[f2];
end;
f1:=top[x];
f2:=top[y];
end;
if c[x]>c[y] then swap(x,y);
ask:=ask+getsum(h[re],,n,c[x],c[y]);
end; begin
readln(n,q);
for i:= to n do
readln(w[i],b[i]);
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
d[]:=;
dfs1();
top[]:=;
dfs2();
t:=;
for i:= to n do
h[b[i]]:=change(h[b[i]],,n,c[i],w[i]);
for i:= to q do
begin
read(ch);
if ch='C' then
begin
readln(ch,x,y);
if ch='C' then
begin
h[b[x]]:=change(h[b[x]],,n,c[x],);
b[x]:=y;
h[y]:=change(h[y],,n,c[x],w[x]);
end
else begin
w[x]:=y;
h[b[x]]:=change(h[b[x]],,n,c[x],y);
end;
end
else begin
readln(ch,x,y);
if ch='M' then
writeln(maxx(x,y))
else writeln(ask(x,y));
end;
end;
end.
bzoj3531的更多相关文章
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- 【BZOJ3531】旅行(树链剖分,线段树)
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
- BZOJ3531 [Sdoi2014]旅行 树链剖分 线段树
原文链接:http://www.cnblogs.com/zhouzhendong/p/8080189.html 题目传送门 - BZOJ3531 题意概括 一棵树,n个节点,每一个节点两个值,一个颜色 ...
- 【bzoj3531】 [SDOI2014]旅行
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...
- Bzoj3531: [Sdoi2014]旅行
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1698 Solved: 758 Description S国有N个城市,编号从1到N.城市间用N-1 ...
- bzoj3531——树链剖分+动态开点线段树
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MB Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连 ...
- 【BZOJ3531】【SDOI2014】旅行
题目传送门 题目大意:给定一棵无根树,每个节点有自己的类别和权值,现在给定两个类别相同的点,叫你求这2点路径上同类别节点的权值和/最大权值. 节点类别与权值会改变. 解题思路:考虑对每一个类别开一棵线 ...
- BZOJ3531 树剖 + 动态开点线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=3531 首先这题意要求树链上的最大值以及求和,其树链剖分的做法已经昭然若揭 问题在于这次的信息有宗教 ...
- BZOJ3531[Sdoi2014]旅行——树链剖分+线段树
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...
随机推荐
- AIX系统上压缩与解压文件
压缩. 命令格式: #tar -cvf (或xvf)+文件名+设备 C:是本地到其他设备 x:是其他设备到本地 r:是追加,比如打包时,将其他文件追加进来使用该参数. t:显示tar包里的内容,但还原 ...
- CentOS 6.7编译安装PHP 5.6
1.准备编译环境 yum install gcc gcc-c++ pcre* openssl* gd-devel* libxml2-devel bzip2-devel libcurl-devel 2. ...
- Bash函数使用
#!/bin/bash function Fun_Name() { #function here echo "this is a function" } Fun_Name
- Castle Windsor Fluent Registration API
一对一注册 直接注册组件 container.Register( Component.For<MyServiceImpl>() ); 注册接口并提供组件 container.Registe ...
- css3 calc()
概述 CSS函数calc()可以用在任何一个需要<length>的地方.有了calc(),你可以通过计算来决定一个对象的大小和形状. 你还可以在一个calc()内部嵌套另一个calc(). ...
- 正则表达式匹配(node.js)
参考文档如下: http://blog.csdn.net/huiguixian/article/details/6131048 http://www.91xueke.com/2013/04/05/30 ...
- linux常用编辑器
管理员在进行系统操作的时候,不可避免地会对文本进行修改,如进行各种服务程序配置文件的改动,使程序对用户提供不同的服务效果.在本章我们向大家介绍Linux上常见的编辑器ed.vi.emacs,同时以vi ...
- android查看真机中的数据库
0.在有网的前提下1.安装 Android Studio,Lantern,Chrome浏览器2.在在githab上搜索stetho,打开第一个facebook/stetho3.在Gradle Scri ...
- WPF DataBinding之我见
原创,转载请注明出处:WPF DataBinding之我见 一.DataBinding介绍 数据绑定是在应用程序 UI 与业务逻辑之间建立连接的过程. 如果绑定具有正确设置并且数据提供正确通知,则 ...
- Codeforces 475 D.CGCDSSQ
题目说了a的范围小于10^9次方,可实际却有超过的数据...真是醉了 算出以f[i]结尾的所有可能GCD值,并统计: f[i]可以由f[i-1]得出. /* 递推算出所有GCD值,map统计 */ # ...