题意:在一棵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. noip2013 火柴排序

    涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: ,其中 ai 表示第一列火柴中第 i 个火柴的高度,b ...

  2. 练习2:雨淋湿了一道题,9个数字只能看清楚4个,第一个肯定不是1 [X * (Y3 + Z)]^2 = 8MN9,求出各个数字

    题目上的X代表的未知数,不一定是同一个数字. 其实这道题,直接一推敲答案就出来了,首先,积德尾数是9,说明 X*(Y3 + Z)的值尾数是3,3的因子只有1和3,所以X只有1和3候选,但是题目说第一个 ...

  3. 在IOS输入框中 键盘上显示“搜索”

    移动端web页面上使用软键盘时如何让其显示“前往”(GO)而不是换行?‘ 用一个 form 表单包裹住就会显示前往,单独的一个 input 就会提示换行.下面是测试地址: 有表单:https://js ...

  4. 反编译dtsi

    dtsi机制是linux kernel为了适配多设备做出来的模块,产品线拉的较长的话用它来控制最合适不过了.初步阅读了下代码和接口清晰简洁. 这个东东出来的时候xml/json应该比较成熟了,疑惑的是 ...

  5. FFmpeg.exe使用随笔

    一.将图片合成为MP4 1.将照片合成为h264 ffmpeg -framerate 12 -i %3d.png -c:v libx264 -pix_fmt yuv420p test.h2642.将h ...

  6. Hello Dojo!(翻译)

    http://dojotoolkit.org/documentation/tutorials/1.10/hello_dojo/index.html 欢迎学习DOJO!在本教程中,你将学些到如何加载DO ...

  7. oracle数据库对象使用说明

    1.创建一个分区表,并插入一些数据,同时查询出每个分区的数据. 答:创建分区表如下 2.创建一个视图,并给出一个查询语句. 3.在当前用户下创建一个同义词,用于查询scott用户下的dept表,并给出 ...

  8. CSS基本知识汇总

    1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets),是一种用来表现 HTML 文档样式的语言,样式定义如何显示 HTML 元素,是能够真正做到网页表现与结构分离的 ...

  9. 深入理解 Laravel Eloquent(三)——模型间关系(关联)

    Eloquent是什么 Eloquent 是一个 ORM,全称为 Object Relational Mapping,翻译为 "对象关系映射"(如果只把它当成 Database A ...

  10. 在linux下获取帮助

    1.使用man手册页 man是一种显示Unix/Linux在线手册的命令.可以用来查看命令.函数或文件的帮助手册,另外它还可以显示一些gzip压缩格式的文件. 读者在遇到不懂的命令时,可以用man查看 ...