【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 ...
随机推荐
- Linux系统常用命令
查找在linux的软件装到哪上面去了,用这个命令dpkg用dpkg命令,比如查pcmanfm这个软件安装到什么地方了用 dpkg -L pcmanfm
- Mac OS X 上Lua的安装方法
先在Mac OS的终端查询下本机是否已安装Lua Last login: Thu Jul 10 07:54:48 on ttys000 keshans-Mac-mini:~ keshan$ lua - ...
- Windows 7上打开IE浏览器报错:无法启动此程序,因为计算机中丢失api-ms-win-core-path-|1-1-0.dll。尝试重新安装该程序以解决此问题。
Windows 7上打开IE浏览器报错: 1. 重新安装IE11也没有解决该问题 2. 在其他Win7电脑也搜索不到该文件,但是能使用IE浏览器. 3. 从网上找了一个dll文件,注册时提示如下图
- JSR 303 - Bean Validation 介绍及最佳实践
JSR 303 - Bean Validation 介绍及最佳实践 JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 ...
- HTML5外包团队-技术分享【使用HTML5的VIDEO标记播放RTSP视频流】
使用HTML5的VIDEO播放RTSP实时视频流源代码: <!DOCTYPE html> <html><head> <meta http-equiv=&quo ...
- spring + spring mvc可能会遇到的问题
Spring容器优先加载由ServletContextListener(对应applicationContext.xml)产生的父容器,而SpringMVC(对应mvc_dispatcher_serv ...
- RNG vs EDG | SKT vs KTB [20160826]
G1 RNG:丽桑卓,古拉加斯,强行开团流. EDG:崔斯特,普朗克,伊莉斯游走,全球支援流,小规模团战能以多打少. G2 RNG:塔莉垭,纳尔,烬. EDG:雷克塞,艾克,劫,冲击后排. G3 RN ...
- [FFmpeg] ffmpeg参数详解
ffmpeg 参数语法 ffmpeg [[options][`-i' input_file]]... {[options] output_file}... 如果没有输入文件,那么视音频捕捉就会起作用. ...
- 黑马程序员_ C语言基础(一)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 开发过程: 编写->编译(只编译源文件,编译成*.o 只会检测语法是否合理,不会检测函数是 ...
- 创建sa账号
①以windows身份验证的方式默认登陆 ②选择安全性下的登录名中的sa账号,右键选择属性,进行相关项的设置 ③将sa账号的状态中对应的登录项由之前的禁用,改为已启用 ④将sa对应的密码进行修改为自己 ...