【POJ3237】Tree(树链剖分)
题意:在一棵N个节点,有边权的树上维护以下操作:
1:单边修改,将第X条边的边权修改成Y
2:区间取反,将点X与Y在树上路径中的所有边边权取反
3:区间询问最大值,询问X到Y树上路径中边权最大值
n<=10000 CAS<=20
思路:做了2天,改出来的一刻全身都萎掉了
边权转点权,点权就是它到父亲的边的边权,加一些反向标记
取反的标记TAG下传时不能直接赋值为-1,而是将原先的标记取反
多组数据时倍增数组,深度也需要清零
树链剖分不能取第一条边,需要+1
const oo=;
var t:array[..]of record
min,max,tag:longint;
end;
f:array[..,..]of longint;
head,vet,next,dep,tid,id,flag,
len,son,size,top,a,b,c,d,g,h:array[..]of longint;
n,m,i,tot,x,y,k,v,cas,time,z,s,tmp,fuhao:longint;
ch:string; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure dfs(u:longint);
var e,v,i,t:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end;
e:=head[u]; flag[u]:=; size[u]:=; son[u]:=; t:=;
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
dep[v]:=dep[u]+;
f[v,]:=u;
dfs(v);
size[u]:=size[u]+size[v];
if size[v]>t then
begin
t:=size[v]; son[u]:=v;
end;
end;
e:=next[e];
end;
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
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 pushdown(l,r,p:longint);
var mid,tmp,t1,t2:longint;
begin
tmp:=t[p].tag;
if (l=r)or(tmp=) then exit;
t[p].tag:=;
t1:=t[p<<].min; t2:=t[p<<].max;
t[p<<].max:=-t1; t[p<<].min:=-t2;
t1:=t[p<<+].min; t2:=t[p<<+].max;
t[p<<+].max:=-t1; t[p<<+].min:=-t2;
t[p<<].tag:=--t[p<<].tag; t[p<<+].tag:=--t[p<<+].tag; end; procedure pushup(p:longint);
begin
t[p].min:=min(t[p<<].min,t[p<<+].min);
t[p].max:=max(t[p<<].max,t[p<<+].max);
end; procedure change(l,r,x,v,p:longint);
var mid:longint;
begin
pushdown(l,r,p);
if (l=x)and(r=x) then
begin
t[p].min:=v; t[p].max:=v;
// t[p].tag:=v;
exit;
end;
mid:=(l+r)>>;
if x<=mid then change(l,mid,x,v,p<<)
else change(mid+,r,x,v,p<<+);
pushup(p);
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; procedure build(l,r,p:longint);
var mid:longint;
begin
if l=r then
begin
if h[id[l]]>oo then
begin
t[p].min:=oo; t[p].max:=-oo;
end
else begin t[p].min:=h[id[l]]; t[p].max:=h[id[l]]; end;
t[p].tag:=;
exit;
end;
mid:=(l+r)>>;
build(l,mid,p<<);
build(mid+,r,p<<+);
pushup(p);
end; function query(l,r,x,y,p:longint):longint;
var mid,t1,t2:longint;
begin
pushdown(l,r,p);
if (l>=x)and(r<=y) then exit(t[p].max);
mid:=(l+r)>>; query:=-oo;
if x<=mid then query:=max(query,query(l,mid,x,y,p<<));
if y>mid then query:=max(query,query(mid+,r,x,y,p<<+));
pushup(p);
end; procedure negate(l,r,x,y,p:longint);
var mid,t1,t2:longint;
begin
pushdown(l,r,p);
if (l>=x)and(r<=y) then
begin
t1:=t[p].min; t2:=t[p].max;
t[p].min:=-t2; t[p].max:=-t1;
t[p].tag:=-;
exit;
end;
mid:=(l+r)>>;
if x<=mid then negate(l,mid,x,y,p<<);
if y>mid then negate(mid+,r,x,y,p<<+);
pushup(p);
end; procedure ngt(x,y:longint);
var q:longint;
begin
q:=lca(x,y);
while top[x]<>top[q] do
begin
negate(,n,tid[top[x]],tid[x],);
x:=f[top[x],];
end;
if tid[q]+<=tid[x] then negate(,n,tid[q]+,tid[x],);
while top[y]<>top[q] do
begin
negate(,n,tid[top[y]],tid[y],);
y:=f[top[y],];
end;
if tid[q]+<=tid[y] then negate(,n,tid[q]+,tid[y],);
end; function ask(x,y:longint):longint;
var q:longint;
begin
q:=lca(x,y);
ask:=-oo;
while top[x]<>top[q] do
begin
ask:=max(ask,query(,n,tid[top[x]],tid[x],));
x:=f[top[x],];
end;
if tid[q]+<=tid[x] then ask:=max(ask,query(,n,tid[q]+,tid[x],));
while top[y]<>top[q] do
begin
ask:=max(ask,query(,n,tid[top[y]],tid[y],));
y:=f[top[y],];
end;
if tid[q]+<=tid[y] then ask:=max(ask,query(,n,tid[q]+,tid[y],));
end; begin
assign(input,'tree.in'); reset(input);
assign(output,'poj3237.out'); rewrite(output);
readln(cas);
for v:= to cas do
begin
readln(n);
fillchar(head,sizeof(head),); tot:=; time:=;
fillchar(flag,sizeof(flag),);
fillchar(d,sizeof(d),); fillchar(g,sizeof(g),);
fillchar(h,sizeof(h),$7f); fillchar(dep,sizeof(dep),);
fillchar(f,sizeof(f),); fillchar(tid,sizeof(tid),);
fillchar(id,sizeof(id),);
for i:= to n<< do
begin
t[i].min:=oo; t[i].max:=-oo; t[i].tag:=;
end;
for i:= to n- do
begin
readln(a[i],b[i],c[i]);
add(a[i],b[i],c[i]);
add(b[i],a[i],c[i]);
end; dfs();
fillchar(flag,sizeof(flag),);
dfs2(,);
for i:= to n- do
begin
if dep[a[i]]<dep[b[i]] then tmp:=b[i]
else tmp:=a[i];
d[i]:=tmp; g[tmp]:=i; h[tmp]:=c[i];
end;
// h[]:=; d[n]:=; g[]:=n;
build(,n,);
while true do
begin
readln(ch); x:=; y:=; k:=length(ch);
if ch[]='D' then break; s:=; fuhao:=;
for i:= to k do
begin
if ch[i]=' ' then begin inc(s); continue; end;
if (s=)and(ch[i]<>' ') then x:=x*+ord(ch[i])-ord('');
if (s=)and(ch[i]<>' ') then
begin
if ch[i]='-' then begin fuhao:=-; continue; end
else y:=y*+ord(ch[i])-ord('');
end;
end;
if ch[]='C' then change(,n,tid[d[x]],fuhao*y,);
if ch[]='N' then ngt(x,y);
if ch[]='Q' then
begin
writeln(ask(x,y));
//writeln;
end;
end;
end;
close(input);
close(output);
end.
【POJ3237】Tree(树链剖分)的更多相关文章
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- poj 3237 Tree 树链剖分
题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...
- Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序
Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...
- poj 3237 Tree 树链剖分+线段树
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
随机推荐
- 记录几款不错的chrome主题
虽然不是一个主题控,但是浏览器无疑是每天使用最多的工具.而在MAC底下,大多数程序边框都是银灰色的,窗口多了就难以有效区分. 所以精挑细选了几款,要求是标签要容易辨识,简洁而不花哨. 不推荐太固定的风 ...
- 在C#中使用C++编写的类
现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类 ...
- mysql操作汇集
1.修改root密码 cmd进如mysql的bin目录 >mysql -u root -p Enter password: ****** mysql> use mysql; mysql&g ...
- testNG设置测试的执行顺序
在java类中,设置Test的执行顺序可以使用priority,或者enabled等属性.但是在testng.xml中,需要设置它的 preserve-order="true" 另 ...
- [转]Mysql命令行常用操作
Mysql命令行常用操作 一.从命令行登录MySQL数据库服务器 1.登录使用默认3306端口的MySQL /usr/local/mysql/bin/mysql -u root -p 2.通过TCP连 ...
- Angular1.x组件通讯方式总结
Angular1开发模式 这里需要将Angular1分为Angular1.5之前和Angular1.5两个不同的阶段来讲,两者虽然同属Angular1,但是在开发模式上还是有较大区别的.在Angula ...
- 【ASP.net】Equals 和 == 的区别
在比较Equals 和 ==的区别前.我们先来了解下相关的知识 C#数据类型 1.值类型 值类型有: 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元. ...
- 再次理解javascript中的事件
一.事件流的概念 + 事件流描述的是从页面中接收事件的顺序. 二.事件捕获和事件冒泡 + 事件冒泡接收事件的顺序:
- bzoj2518: [Shoi2010]滚动的正四面体
Description 正四面体总共有4个面,每个面都是一个正三角形.现在把它的一个面标记上字母A,如图 3中所示,A标记在底面上: 于是,这个正四面体的滚动过程就可以用一个只包含“L”“R”“B”的 ...
- UVA 1658 海军上将(拆点法+最小费用限制流)
海军上将 紫书P375 这题我觉得有2个难点: 一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点. 二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制 ...