肯定是树链剖分+线段树,关键是怎么维护

绝对值和这个东西显然不能简单的合并标记

因为对于负数,加之后绝对值和是变小的

那我们考虑对负数和非负数数分别维护

下面的问题就是经过操作如果负数变成了正数怎么办

注意每次加的都是正数,这意味着这样的变化最多发生n次,

每个数发生这种变化,我们就用push到底即可,这样最多nlogn的

所以我们只要在维护一个区间最大负数即可

 const inf=;
type node=record
po,next:longint;
end;
link=record
s0,s1,mx:int64;
s:longint;
end; var tree:array[..*] of link;
lazy:array[..*] of int64;
e:array[..*] of node;
top,fa,a,b,c,d,p,s:array[..] of longint;
t,i,x,y,ch,z,len,n,m:longint; function max(a,b:int64):int64;
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 add(x,y:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
p[x]:=len;
end; procedure dfs1(x:longint);
var i,y:longint;
begin
i:=p[x];
s[x]:=;
while i<> do
begin
y:=e[i].po;
if s[y]= then
begin
fa[y]:=x;
d[y]:=d[x]+;
dfs1(y);
s[x]:=s[x]+s[y];
end;
i:=e[i].next;
end;
end; procedure dfs2(x:longint);
var q,i,y:longint;
begin
inc(t);
c[x]:=t;
b[t]:=x;
i:=p[x];
q:=;
while i<> do
begin
y:=e[i].po;
if c[y]= then
if s[y]>s[q] then q:=y;
i:=e[i].next;
end;
if q<> then
begin
top[q]:=top[x];
dfs2(q);
end;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if c[y]= then
begin
top[y]:=y;
dfs2(y);
end;
i:=e[i].next;
end;
end; procedure update(i:longint);
begin
tree[i].s0:=tree[i*].s0+tree[i*+].s0;
tree[i].s1:=tree[i*].s1+tree[i*+].s1;
tree[i].s:=tree[i*].s+tree[i*+].s;
tree[i].mx:=max(tree[i*].mx,tree[i*+].mx);
end; procedure build(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
if a[b[l]]>= then
begin
tree[i].s0:=a[b[l]];
tree[i].s:=;
tree[i].mx:=-inf;
end
else begin
tree[i].s1:=a[b[l]];
tree[i].mx:=a[b[l]];
end;
end
else begin
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
update(i);
end;
end; procedure modi(i,len:longint; z:int64);
begin
inc(lazy[i],z);
inc(tree[i].mx,z);
inc(tree[i].s0,int64(tree[i].s)*z);
inc(tree[i].s1,int64(len-tree[i].s)*z);
end; procedure push(i,l,r:longint);
var m:longint;
begin
m:=(l+r) shr ;
modi(i*,m-l+,lazy[i]);
modi(i*+,r-m,lazy[i]);
lazy[i]:=;
end; procedure down(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
tree[i].s0:=tree[i].mx;
tree[i].s:=;
tree[i].mx:=-inf;
tree[i].s1:=;
end
else begin
m:=(l+r) shr ;
if lazy[i]<> then push(i,l,r);
if tree[i*].mx>= then down(i*,l,m);
if tree[i*+].mx>= then down(i*+,m+,r);
update(i);
end;
end; procedure ins(i,l,r,x,y:longint);
var m:longint;
begin
if (x<=l) and (y>=r) then
begin
if tree[i].mx+z>= then
begin
inc(lazy[i],z);
inc(tree[i].mx,z);
down(i,l,r);
end
else modi(i,r-l+,z);
end
else begin
if lazy[i]<> then push(i,l,r);
m:=(l+r) shr ;
if x<=m then ins(i*,l,m,x,y);
if y>m then ins(i*+,m+,r,x,y);
update(i);
end;
end; function get(i,l,r,x,y:longint):int64;
var m:longint;
s:int64; begin
if (x<=l) and (y>=r) then exit(tree[i].s0+abs(tree[i].s1))
else begin
if lazy[i]<> then push(i,l,r);
m:=(l+r) shr ;
s:=;
if x<=m then s:=s+get(i*,l,m,x,y);
if y>m then s:=s+get(i*+,m+,r,x,y);
exit(s);
end;
end; procedure work(x,y:longint);
var f1,f2:longint;
begin
f1:=top[x];
f2:=top[y];
while f1<>f2 do
begin
if d[f1]>=d[f2] then
begin
ins(,,n,c[f1],c[x]);
x:=fa[f1];
f1:=top[x];
end
else begin
ins(,,n,c[f2],c[y]);
y:=fa[f2];
f2:=top[y];
end;
end;
if c[x]>c[y] then swap(x,y);
ins(,,n,c[x],c[y]);
end; function ask(x,y:longint):int64;
var f1,f2:longint;
begin
ask:=;
f1:=top[x];
f2:=top[y];
while f1<>f2 do
begin
if d[f1]>=d[f2] then
begin
ask:=ask+get(,,n,c[f1],c[x]);
x:=fa[f1];
f1:=top[x];
end
else begin
ask:=ask+get(,,n,c[f2],c[y]);
y:=fa[f2];
f2:=top[y];
end;
end;
if c[x]>c[y] then swap(x,y);
ask:=ask+get(,,n,c[x],c[y]);
end; begin
readln(n,m);
for i:= to n do
read(a[i]);
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
dfs1();
top[]:=;
dfs2();
build(,,n);
for i:= to m do
begin
read(ch,x,y);
if ch= then
begin
readln(z);
work(x,y);
end
else begin
readln;
writeln(ask(x,y));
end;
end;
end.

bzoj4127的更多相关文章

  1. [bzoj4127]Abs_树链剖分_线段树

    Abs bzoj-4127 题目大意:给定一棵数,支持链加和链上权值的绝对值的和. 注释:$1\le n,m \le 10^5$,$\delta \ge 0$,$|a_i|\le 10^8$. 想法: ...

  2. 【BZOJ-4127】Abs 树链剖分 + 线段树 (有趣的姿势)

    4127: Abs Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 381  Solved: 132[Submit][Status][Discuss] ...

  3. BZOJ4127: Abs

    Description 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 Input 第一行两个整数n和m,表 ...

  4. 【bzoj4127】Abs 树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  5. bzoj4127 Abs 树链剖分+线段树+均摊分析

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4127 题解 首先区间绝对值和可以转化为 \(2\) 倍的区间正数和 \(-\) 区间和.于是问 ...

随机推荐

  1. 停止使用循环 教你用underscore优雅的写代码

    你一天(一周)内写了多少个循环了? var i; for(i = 0; i < someArray.length; i++) {   var someThing = someArray[i]; ...

  2. eclipse sdk 无法更新

    最近祖国越来越强了,强得android开发工具都没法更新了,但是祖国再怎么强也阻挡不了我开发的脚步.下面给大家分享个更新android sdk 的方法.方法原理就是利用国内镜像源. 工具/原料 电脑一 ...

  3. D3D Deferred Shading

    在3D图形计算中,deferred shading是一个基于屏幕空间的着色技术.之所以被称为deferred shading,是因为我们将场景的光照计算与渲染"deferred"到 ...

  4. .net 类型源码下载地址

    原文:http://www.cnblogs.com/ProJKY/p/SSCLI.html 一般场景下,采用 Reflector可以反射出.NET 的部分实现出来,可以拿来参考,但和微软公开的SSCL ...

  5. 斌哥的 Docker 进阶指南—监控方案的实现

    过去的一年中,关于 Docker 的话题从未断过,而如今,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减.另一方面,大家的注意力也渐 ...

  6. cf div2 238 D

    D. Toy Sum time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  7. ***Jquery下Ajax与PHP数据交换

    一.前台传递字符串变量,后台返回字符串变量(非json格式) Javascript代码: 这里,为了解决Ajax数据传递出现的汉字乱码,在字符串传递之前,使用javascript函数escape()对 ...

  8. URAL 1183 Brackets Sequence(DP)

    题目链接 题意 : 给你一串由括号组成的串,让你添加最少的括号使该串匹配. 思路 : 黑书上的DP.dp[i][j] = min{dp[i+1][j-1] (sh[i] == sh[j]),dp[i] ...

  9. LINUX进程控制

    1. 引言 一个程序是存储在文件中的机器指令序列.一般它是由编译器将源代码编译成二进制格式的代码.运行一个程序意味着将这个机器指令序列载入内存然后让处理器(cpu)逐条执行这些指令. 在Unix术语中 ...

  10. HtmlAgilityPack 之 HtmlNode类

    HtmlAgilityPack中的HtmlNode类与XmlNode类差不多,提供的功能也大同小异.下面来看看该类提供功能. 一.静态属性 public static Dictionary<st ...