bzoj4127
肯定是树链剖分+线段树,关键是怎么维护
绝对值和这个东西显然不能简单的合并标记
因为对于负数,加之后绝对值和是变小的
那我们考虑对负数和非负数数分别维护
下面的问题就是经过操作如果负数变成了正数怎么办
注意每次加的都是正数,这意味着这样的变化最多发生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的更多相关文章
- [bzoj4127]Abs_树链剖分_线段树
Abs bzoj-4127 题目大意:给定一棵数,支持链加和链上权值的绝对值的和. 注释:$1\le n,m \le 10^5$,$\delta \ge 0$,$|a_i|\le 10^8$. 想法: ...
- 【BZOJ-4127】Abs 树链剖分 + 线段树 (有趣的姿势)
4127: Abs Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 381 Solved: 132[Submit][Status][Discuss] ...
- BZOJ4127: Abs
Description 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 Input 第一行两个整数n和m,表 ...
- 【bzoj4127】Abs 树链剖分+线段树
题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...
- bzoj4127 Abs 树链剖分+线段树+均摊分析
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4127 题解 首先区间绝对值和可以转化为 \(2\) 倍的区间正数和 \(-\) 区间和.于是问 ...
随机推荐
- Create Script Template In Edit Mode
很多时候 许多类 的 格式 都是重复的,比如 从配置文件中映射出来的类. 这个时候写一个 类模板 就很节省时间了. Code public static string TestPath = " ...
- 通过登入IP记录Linux所有用户登录所操作的日志
通过登入IP记录Linux所有用户登录所操作的日志 对于Linux用户操作记录一般通过命令history来查看历史记录,但是如果在由于误操作而删除了重要的数据的情况下,history命令就不会有什么作 ...
- HTML5 canvas 绘图步骤
1.先把canvas选出来,不选出来你往哪儿画! var oCan= document.getElementById('xxx'); 2.声明基于 canvas 的context对象,没他你怎么调用 ...
- sream bytes[] img相互转换
/// <summary> /// 将 Stream 转成 byte[] /// </summary> /// <param name="stream" ...
- hdu 4745 Two Rabbits
思路:求最长回文子串的长度!代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #incl ...
- JAVA IO 体系
一.体系结构
- C#日期大全
DateTime dt = DateTime.Now; // Label1.Text = dt.ToString();//2005-11-5 13:21:25 // Label2.Text = dt. ...
- No ResultSet was produced
遇到的详细问题: 出现了No ResultSet was produced的异常,但数据是成功插入, 大致判断异常发生在执行插入操作后,检查代码. 解决方案: 通常在executeQuery(sql) ...
- 【android原生应用】之闹钟应用搭起篇
由于工作原因接触android开发一段时间了,对于开发有了一些了解,于是萌生了搭起android原生应用进行分析和学习的想法.先从闹钟应用开始吧. 1.首先要下载原生应用,原生应用在原生系统里面(当然 ...
- 图解TCP/IP读书笔记(二)
图解TCP/IP读书笔记(二) 第二章.TCP/IP基础知识 一.TCP/IP出现的背景及其历史 年份 事件 20世纪60年代后半叶 应DoD(美国国防部)要求,美国开始进行通信技术相关的研发 196 ...