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. Linux 命令 - scp: 远程文件拷贝

    scp 与普通的文件复制命令 cp 类似,而它们之间最大的差别在于 scp 命令的源或目标文件是远程文件. 命令格式 scp [options] [[user@]host1:]file1 ... [[ ...

  2. Nginx - Events Module

    The Events module comes with directives that allow you to configure network mechanisms. Some of the ...

  3. WebAPI GET和POST请求的几种方式

    GET请求 1.无参数get请求 一般get请求有两种写法,一种是$.get()   一种是$.ajax({type:"get"}),我个人比较喜欢用后者. 下面例子主要是get无 ...

  4. pdf文件流生成pdf文件

    protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { Code.Login Starr_mode ...

  5. webBrowser1_DocumentCompleted不停被调用

    原文地址:http://blog.csdn.net/shuishenlong/article/details/7950576 关于DocumentCompleted事件,MSDN给出的解释是在文档加载 ...

  6. linux中sed用法

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为:         sed ...

  7. 承接VR/AR内容应用定制需求

    业务范围: 1 承接VR/AR内容应用定制需求: 教育培训.建筑建设.旅游体验.课件教学系统.交通车辆仿真,模拟驾驶系统.游戏等.2 各类最新VR设备,例如GearVR.HTC vive.Oculus ...

  8. NSURLSession的使用(1)

    一.创建一个Session,并且对其进行初始化 包含三种创建方式:   1.+ (NSURLSession *)sharedSession  单例模式 2.+ (NSURLSession *)sess ...

  9. windows下redis服务安装

    1.redis简介redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...

  10. OpenCV基本架构[OpenCV 笔记0]

    最近正在系统学习OpenCV,将不定期发布笔记,主要按照毛星云的<OpenCV3编程入门>的顺序学习,会参考官方教程和文档.学习工具是Xcode+CMake,会对书中一部分内容更正,并加入 ...