【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 ...
随机推荐
- mysql source命令超大文件导入方法总结
本文章来给各位朋友介绍利用mysql source命令超大文件导入方法总结,下面收集了两种解决办法,一种是把数据库分文件导出然后再导入,另一种是修改my.ini配置文件,下面我一一给各位朋友介绍. 导 ...
- php iquery
<?php/** * */function iQuery($sql) { $dbcon = mysqli_connect("localhost", "root&qu ...
- centos网卡eth1变成eth0修改方法
centos网卡eth1变成eth0修改方法 2013年03月29日 ⁄ Linux基础 ⁄ 共 406字 ⁄ 暂无评论 ⁄ 被围观 8,266 views+ 虚拟化中,从模板克隆出来的虚拟机网卡都会 ...
- Maven学习5-聚合与继承
一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module&g ...
- 【转】linux 编译安装nginx,配置自启动脚本
linux 编译安装nginx,配置自启动脚本 本文章来给各位同学介绍一篇关于linux 编译安装nginx,配置自启动脚本教程,希望有需要了解的朋友可一起来学习学习哦. 在公司的suse服务器装ng ...
- 如何创建 CSS
如何插入样式表 当读到一个样式表时,浏览器会根据它来格式化 HTML 文档.插入样式表的方法有三种: 外部样式表 当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以 ...
- -include和sinclude 作用
-include和sinclude 如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误.它 会继续载入其它的文件,一旦完成makefile的读取,make会再重试这些没有找 ...
- ASP.net 关于TextBox的TextMode=“PassWord”时的动态赋值
1.在界面创建一个新的TBPwdTemp并设置TextMode=“SingleLine”,visible=“false”,将数据库密码值传给该TextBox: 2.然后分别用 this.TBPwd.A ...
- bzoj2006 noi2010 超级钢琴 主席树 + 优先队列
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2435 Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...
- python(24)urlencode和urldecode
当url地址含有中文,或者参数有中文的时候,这个算是很难正常了,但是把这样的url作为参数传递的时候(最常见的callback),需要把一些中文甚至‘/’做一下编码转换. 一.urlencode ur ...