[BZOJ3999] [TJOI2015]旅游
2016-02-22 10:45
351 查看
传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=3999题目大意
给定一棵树,树上有权值,要求支持查询树上两点a—>b(有方向)a—>b(有方向)间路径上max(xj−xi)max(x_j-x_i)且j到a的距离比i大j到a的距离比i大
以及路径整体+c+c
题解
树链剖分+线段树合并注意细节!!
const maxn=50040; type data=record a1,a2,minn,maxx:longint; end; var w:array[0..3*maxn,1..2]of longint; x,fa,son,size,dep,top,pos:array[0..maxn]of longint; seg:array[0..4*maxn,1..7]of longint; i,j,k:longint; n,m,len,a,b,c:longint; function max(a,b:longint):Longint; begin if a>b then exit(a) else exit(b); end; function min(a,b:longint):Longint; begin if a<b then exit(a) else exit(b); end; procedure swap(var a,b:longint); var c:longint; begin c:=a; a:=b; b:=c; end; procedure init(a,b:longint); begin w[len,1]:=b; if w[a,2]=0 then w[a,2]:=len else w[w[a,1],2]:=len; w[a,1]:=len; inc(len); end; procedure build(a,l,r:longint); var mid:longint; begin seg[a,1]:=l; seg[a,2]:=r; seg[a,3]:=0; seg[a,4]:=0; seg[a,5]:=0; seg[a,6]:=0; seg[a,7]:=0; if l=r then exit; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); end; procedure pushdown(a:longint); begin if seg[a,1]=seg[a,2] then begin seg[a,5]:=0; exit; end; inc(seg[a<<1,3],seg[a,5]); inc(seg[a<<1+1,3],seg[a,5]); inc(seg[a<<1,4],seg[a,5]); inc(seg[a<<1+1,4],seg[a,5]); inc(seg[a<<1,5],seg[a,5]); inc(seg[a<<1+1,5],seg[a,5]); seg[a,5]:=0; end; procedure update(a,l,r,c:longint); var mid:longint; begin if seg[a,5]<>0 then pushdown(a); if (seg[a,1]=l)and(seg[a,2]=r) then begin inc(seg[a,3],c); inc(seg[a,4],c); inc(seg[a,5],c); exit; end; mid:=(seg[a,1]+seg[a,2])>>1; if r<=mid then update(a<<1,l,r,c) else if l>mid then update(a<<1+1,l,r,c) else begin update(a<<1,l,mid,c); update(a<<1+1,mid+1,r,c); end; seg[a,3]:=min(seg[a<<1,3],seg[a<<1+1,3]); seg[a,4]:=max(seg[a<<1,4],seg[a<<1+1,4]); seg[a,6]:=max(max(seg[a<<1,6],seg[a<<1+1,6]),seg[a<<1,4]-seg[a<<1+1,3]); seg[a,7]:=max(max(seg[a<<1,7],seg[a<<1+1,7]),seg[a<<1+1,4]-seg[a<<1,3]) end; function query(a,l,r:longint):data; var mid:longint; t1,t2,ans:data; begin if seg[a,5]<>0 then pushdown(a); if (seg[a,1]=l)and(seg[a,2]=r) then begin ans.minn:=seg[a,3]; ans.maxx:=seg[a,4]; ans.a1:=seg[a,6]; ans.a2:=seg[a,7]; exit(ans); end; mid:=(seg[a,1]+seg[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else begin t1:=query(a<<1,l,mid); t2:=query(a<<1+1,mid+1,r); ans.minn:=min(t1.minn,t2.minn); ans.maxx:=max(t1.maxx,t2.maxx); ans.a1:=max(max(t1.a1,t2.a1),t1.maxx-t2.minn); ans.a2:=max(max(t1.a2,t2.a2),t2.maxx-t1.minn); exit(ans); end; end; procedure dfs1(a:longint); var tt,v:longint; begin tt:=w[a,2]; size[a]:=1; v:=0; while tt<>0 do begin if w[tt,1]<>fa[a] then begin fa[w[tt,1]]:=a; dep[w[tt,1]]:=dep[a]+1; dfs1(w[tt,1]); inc(size[a],size[w[tt,1]]); if size[w[tt,1]]>size[v] then v:=w[tt,1]; end; tt:=w[tt,2]; end; son[a]:=v; end; procedure dfs2(a,pre:longint); var tt:longint; begin tt:=w[a,2]; inc(len); pos[a]:=len; top[a]:=pre; update(1,len,len,x[a]); if son[a]<>0 then dfs2(son[a],pre); while tt<>0 do begin if (w[tt,1]<>son[a])and(w[tt,1]<>fa[a]) then dfs2(w[tt,1],w[tt,1]); tt:=w[tt,2]; end; end; procedure queryans(a,b,c:longint); var t1,t2,tt:data; begin t1.maxx:=0; t1.minn:=maxlongint; t1.a1:=0; t1.a2:=0; t2.maxx:=0; t2.minn:=maxlongint; t2.a1:=0; t2.a2:=0; while top[a]<>top[b] do begin if dep[top[a]]>dep[top[b]] then begin tt:=query(1,pos[top[a]],pos[a]); t1.a1:=max(max(t1.a1,tt.a1),tt.maxx-t1.minn); t1.maxx:=max(t1.maxx,tt.maxx); t1.minn:=min(t1.minn,tt.minn); update(1,pos[top[a]],pos[a],c); a:=fa[top[a]]; end else begin tt:=query(1,pos[top[b]],pos[b]); t2.a2:=max(max(t2.a2,tt.a2),t2.maxx-tt.minn); t2.maxx:=max(t2.maxx,tt.maxx); t2.minn:=min(t2.minn,tt.minn); update(1,pos[top[b]],pos[b],c); b:=fa[top[b]]; end; end; if dep[a]<dep[b] then begin tt:=query(1,pos[a],pos[b]); t2.a2:=max(max(t2.a2,tt.a2),t2.maxx-tt.minn); t2.maxx:=max(t2.maxx,tt.maxx); t2.minn:=min(t2.minn,tt.minn); writeln(max(max(t1.a1,t2.a2),t2.maxx-t1.minn)); update(1,pos[a],pos[b],c); end else begin tt:=query(1,pos[b],pos[a]); t1.a1:=max(max(t1.a1,tt.a1),tt.maxx-t1.minn); t1.maxx:=max(t1.maxx,tt.maxx); t1.minn:=min(t1.minn,tt.minn); writeln(max(max(t1.a1,t2.a2),t2.maxx-t1.minn)); update(1,pos[b],pos[a],c); end; end; begin readln(n); len:=n+1; for i:=1 to n do read(x[i]); for i:=1 to n-1 do begin readln(a,b); init(a,b); init(b,a); end; fa[1]:=0; dep[1]:=1; size[0]:=0; dfs1(1); len:=0; build(1,1,n); dfs2(1,1); readln(m); for i:=1 to m do begin readln(a,b,c); queryans(a,b,c); end; end.
相关文章推荐
- NFS文件系统初识
- java中abstract详解
- 类型强制转换符 与 + 符的优先级
- mui几种页面跳转方式对比
- UIView与CALayer的区别,很详细
- android刷新媒体库
- HTML5地理定位,百度地图API,知识点熟悉
- 自动删除n天前日志
- libvirt源代码安装
- Java 回顾笔记5(上午)_static
- 2015:JavaScript 之于物联网
- iOS中程序代码存储区块
- 深复制和浅复制的概念
- Golang语法总结(二):程序结构
- JSON与Java对象转换
- jQuery之ajax
- iOS中block的使用注意
- 单例的两种写法
- 深圳郎仁科技iobd2利用代码
- GCD的相关知识