题意:在一棵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(树链剖分)的更多相关文章

  1. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  2. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  3. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  4. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  5. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  6. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  7. poj 3237 Tree 树链剖分

    题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...

  8. Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序

    Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...

  9. poj 3237 Tree 树链剖分+线段树

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  10. 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 ...

随机推荐

  1. mysql 把文件中的sql语句导入到mysql中

    mysql -uroot -proot -Dcollege</home/wwwroot/default/data/xlxxb_2014-10-16.txt;

  2. Python-select详解(select、epoll)

    select函数操作集合的时候有个要求,要么集合本身是描述符,要么他提供一个fileno()接口,返回一个描述符. I/O多路复用是在单线程模式下实现多线程的效果,实现一个多I/O并发的效果.看一个简 ...

  3. SQL ServerOVER 子句,over开窗函数,SQL SERVER 开窗函数

    https://technet.microsoft.com/zh-cn/library/ms189461(v=sql.105).aspx http://www.cnblogs.com/85538649 ...

  4. Redis部分数据结构方法小结

    package com.practice.util; import java.util.HashMap; import java.util.List; import java.util.Map; im ...

  5. UML精粹3 - 类图,序列图,CRC

    类图Class diagram 类图描述系统中的对象类型,以及它们之间的各种静态关系.类图也展示类的性质和操作,以及应用于对象连接方式的约束.UML中的特性feature,涵盖了性质property和 ...

  6. svn 提交失败

    刚刚使用SVN 提交代码时提示失败. svn: Commit failed (details follow):svn: Can't open file '/home/svn/project/db/tx ...

  7. iframe自适应高度(兼容IE 火狐 谷歌)

    <div id="leamain"> <iframe src="#" marginheight="0" marginwid ...

  8. 大众点评试题分析(C/C++)

    1.main函数执行完毕,从栈中弹出操作函数 void fn1(void), fn2(void), fn3(void); int main() { atexit(fn3); atexit(fn1); ...

  9. 魅族手机(魅蓝note)无法作为调试设备连接到mac问题的解决

    问题描述: OS X(Yosemite),ADB(1.0.32),Android Studio(1.0.1),魅蓝note手机(m1 note,Android 4.4.4,Flyme OS 4.2.0 ...

  10. debian8(jessie)安装小记

    其实上周五就想写这篇博客了,一直忙着没时间,虽然也不知道自己这一个星期到底在忙什么.这次我是彻底告别windows了,安装的过程略为艰辛,因为之前习惯了deepin和ubuntu的傻瓜式安装,而deb ...