Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ).

You have to apply Q ( Q<=100000 ) operations:

1. 1 a b : answer the maximum contiguous sum (maybe empty,will always larger than or equal to 0 ) from the path a->b ( inclusive ).

2. 2 a b c : change all value in the path a->b ( inclusive ) to c.
Input

first line consists one interger N.

next line consists N interger x_i.

next N-1 line , each consists two interger u,v , means that node u and node v are connected

next line consists 1 interger Q.

next Q line : 1 a b or 2 a b c .
Output

For each query, output one line the maximum contiguous sum.
Example

Input:
5

-3 -2 1 2 3

1 2

2 3

1 4

4 5

3

1 2 5

2 3 4 2

1 2 5

Output:
5

9

GSS系列最后一道题终于攻破

树链剖分可做,不过代码很长,280行.....

酝酿了这么久终于写了,以前一直不敢做,今天觉得是时候了

又认真看了一遍入门http://blog.sina.com.cn/s/blog_7a1746820100wp67.html

用了一个下午的时间把它AC了,觉得很欣慰,竟然是一次AC,幸福来得太突然.....

 const
inf=-maxlongint;
type
node=record
lson,rson,left,right,lmax,rmax,amax,lazy,sum:longint;
end; var
tree:array[..]of node;
first,next,last:array[..]of longint;
son,fa,size,dep,w,top,root,a:array[..]of longint;
flag:array[..]of boolean;
tot,n,num,ll,rr:longint; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure insert(x,y:longint);
begin
inc(num);
last[num]:=y;
next[num]:=first[x];
first[x]:=num;
end; procedure dfs1(x,d,f:longint);
var
i,j:longint;
begin
fa[x]:=f;
flag[x]:=true;
dep[x]:=d;
size[x]:=;
i:=first[x];
j:=;
while i<> do
begin
if flag[last[i]]=false then
begin
dfs1(last[i],d+,x);
inc(size[x],size[last[i]]);
if size[last[i]]>size[j] then j:=last[i];
end;
i:=next[i];
end;
son[x]:=j;
end; procedure build(l,r:longint);
var
now,mid:longint;
begin
inc(tot);
now:=tot;
with tree[now] do
begin
left:=l;
right:=r;
lazy:=inf;
end;
if l=r then exit;
mid:=(l+r)>>;
with tree[now] do
begin
lson:=tot+;
build(l,mid);
rson:=tot+;
build(mid+,r);
end;
end; procedure new(x,now:longint);
begin
with tree[now] do
begin
if left<>right then lazy:=x;
sum:=x*(right-left+);
amax:=max(,sum);
lmax:=amax;
rmax:=amax;
end;
end; procedure down(now:longint);
begin
with tree[now] do
begin
new(lazy,lson);
new(lazy,rson);
lazy:=inf;
end;
end; procedure up(now:longint);
begin
with tree[now] do
begin
sum:=tree[lson].sum+tree[rson].sum;
amax:=max(max(tree[lson].amax,tree[rson].amax),tree[lson].rmax+tree[rson].lmax);
lmax:=max(tree[lson].lmax,tree[lson].sum+tree[rson].lmax);
rmax:=max(tree[rson].rmax,tree[rson].sum+tree[lson].rmax);
end;
end; procedure change(x,now:longint);
var
mid:longint;
begin
with tree[now] do
begin
if(ll<=left)and(rr>=right) then
begin
new(x,now);
exit;
end;
if lazy<>inf then down(now);
mid:=(left+right)>>;
if rr>mid then change(x,rson);
if ll<=mid then change(x,lson);
up(now);
end;
end; procedure dfs2(x,t,ww:longint);
var
i:longint;
begin
flag[x]:=false;
top[x]:=t;
w[x]:=ww;
if son[x]= then
begin
root[x]:=tot+;
build(,ww);
ll:=ww;
rr:=ww;
change(a[x],root[x]);
exit;
end;
dfs2(son[x],t,ww+);
root[x]:=root[son[x]];
ll:=ww;
rr:=ww;
change(a[x],root[x]);
i:=first[x];
while i<> do
begin
if flag[last[i]] then dfs2(last[i],last[i],);
i:=next[i];
end;
end; procedure init;
var
i,x,y:longint;
begin
read(n);
for i:= to n do
read(a[i]);
for i:= to n- do
begin
read(x,y);
insert(x,y);
insert(y,x);
end;
dfs1(,,);
dfs2(,,);
end; procedure get(var am,lm,rm,su:longint;now:longint);
var
mid:longint;
begin
with tree[now] do
begin
if lazy<>inf then down(now);
if(ll<=left)and(rr>=right) then
begin
am:=max(max(am,amax),lm+rmax);
lm:=max(lmax,sum+lm);
rm:=max(rm,su+rmax);
su:=su+sum;
exit;
end;
mid:=(left+right)>>;
if rr>mid then get(am,lm,rm,su,rson);
if ll<=mid then get(am,lm,rm,su,lson);
end;
end; procedure work1;
var
x,y,amax1,lmax1,rmax1,sum1,amax2,lmax2,rmax2,sum2:longint;
begin
read(x,y);
amax1:=;
lmax1:=;
rmax1:=;
sum1:=;
amax2:=;
lmax2:=;
rmax2:=;
sum2:=;
if dep[top[x]]<dep[top[y]] then swap(x,y);
while top[x]<>top[y] do
begin
ll:=;
rr:=w[x];
get(amax1,lmax1,rmax1,sum1,root[x]);
x:=fa[top[x]];
if dep[top[x]]<dep[top[y]] then
begin
swap(x,y);
swap(amax1,amax2);
swap(lmax1,lmax2);
swap(rmax1,rmax2);
swap(sum1,sum2);
end;
end;
if dep[x]<dep[y] then
begin
swap(x,y);
swap(amax1,amax2);
swap(lmax1,lmax2);
swap(rmax1,rmax2);
swap(sum1,sum2);
end;
ll:=w[y];
rr:=w[x];
get(amax1,lmax1,rmax1,sum1,root[x]);
writeln(max(max(amax1,amax2),lmax1+lmax2));
end; procedure work2;
var
x,y,z:longint;
begin
read(x,y,z);
if dep[top[x]]<dep[top[y]] then swap(x,y);
while top[x]<>top[y] do
begin
ll:=;
rr:=w[x];
change(z,root[x]);
x:=fa[top[x]];
if dep[top[x]]<dep[top[y]] then swap(x,y);
end;
if dep[x]<dep[y] then swap(x,y);
ll:=w[y];
rr:=w[x];
change(z,root[x]);
end; procedure work;
var
i,q,s:longint;
begin
read(q);
for i:= to q do
begin
read(s);
if s= then work1
else work2;
end;
end; begin
init;
work;
end.

6779. Can you answer these queries VII - SPOJ的更多相关文章

  1. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  2. SPOJ GSS7 - Can you answer these queries VII

    板的不能再板,链剖+线段树或者是LCT随便维护. 感觉唯一要注意的是跳链的时候要对$x$向上跳和$y$向上跳的情况分开讨论,而不能直接$swap$,因为只有两段接触的端点才能相互合并,而且每一次向上跳 ...

  3. SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树

    [题目分析] 问题放到了树上,直接链剖+线段树搞一搞. 调了300行+. (还是码力不够) [代码] #include <cstdio> #include <cstring> ...

  4. Can you answer these queries I SPOJ - GSS1 (线段树维护区间连续最大值/最大连续子段和)

    You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defi ...

  5. Can you answer these queries(spoj 1043)

    题意:多次查询区间最长连续字段和 /* 用线段树维护区间最长子段和,最长左子段和,最长右子段和. */ #include<cstdio> #include<iostream> ...

  6. Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)

    recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...

  7. SP6779 GSS7 - Can you answer these queries VII

    纯数据结构题,没有思维难度.直接用线段树求最大子段和的方法完成树上路径的合并.注意链上合并顺序要符合序列的前后顺序. #include <cstdio> #include <cstr ...

  8. 题解 SP6779 【GSS7 - Can you answer these queries VII】

    题目传送门 题目大意 给出一个\(n\)个点的树,每个点有权值.有\(m\)次操作,每次要么查询一条链上的最大子段和,要么把一条链的权值都修改为一个常数. \(n,m\le 10^5\) 思路 如果是 ...

  9. SP6779 GSS7 - Can you answer these queries VII(线段树,树链剖分)

    水题,只是坑点多,\(tag\)为\(0\)时可能也要\(pushdown\),所以要\(bool\)标记是否需要.最后树链剖分询问时注意线段有向!!! #include <cstring> ...

随机推荐

  1. http状态代码含义表

    100 - 表示已收到请求的一部分,正在继续发送余下部分. 101 - 切换协议. 2xx - 成功.服务器成功地接受了客户端请求: 200 - 确定.客户端请求已成功. 201 - 已创建. 202 ...

  2. HDOJ2002计算球体积

    计算球体积 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  3. C#中的二进制序列化和Json序列化

    序列化就是把一个对象变成流的形式,方便传输和还原.小弟不才,总结下对二进制序列化和Json序列化的使用: 1.首先,二进制序列化(BinaryFormatter)要求要序列化的类必须是可序列化的(即在 ...

  4. 企业SAAS的春天,将以手机应用的形式,即将到来

    派尔科技吴春福 *本文是派尔为什么要投身企业移动应用的内部分享文章: *我没有仔细核查资料,仅代表个人看法,思路也是在整理过程,逻辑未必很完整,看官将就着看. 企业SAAS,概念起源是N年前,先行者也 ...

  5. 第五十四篇、OC利用AFN上传上传语音

    如果不是NSData就要想办法把语音文件转化为NSData,然后才能上传服务器. 首先我们拿到语音文件对应的NSData对象 NSData *voiceData = [message valueFor ...

  6. iOS - 视图与手势(UIview & UIGestureRecognizer)

    01 UIView视图的基本使用 --- 在根视图中添加2个UIView视图 //视图确实加载时调用 - (void)viewDidLoad { [super viewDidLoad]; // Do ...

  7. DOM_节点层次_Document类型

    一.Document类型 nodeType: 9; nodeName: "#document"; nodeValue: null; parentValue: null; owner ...

  8. Smarty模板引擎技术二

    Smarty模板引擎技术 内建函数 include_php内建函数 作用:载入一个php文件,将载入的文件的内容赋值给一个变量   注意:该内建函数只能在2.0中使用,如果使用的话,必须得实例化Sma ...

  9. log4j定义某个类的日志级别

    项目引入了定时任务后,当我把已有的定时任务删除后,控制台一直会打出类似于 [org.springframework.scheduling.quartz.LocalDataSourceJobStore] ...

  10. 3月3日(2) Search Insert Position

    这题...有点简单吧,为什么只有34%的通过率? 题目意思简单说就是查找index,或者按升序插入的未知,WA一次,罪过,下次要特别注意程序里变量的变化,提交前用样例检查. 简单的我有点不好意思贴代码 ...