题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4127

不算难的样子,才见过此类模型。

首先可以发现每次修改只增不减,那么这$O(n)$的负数最多只会有$n$次由负变正。

所以对于每一次由负变正我们暴力在线段树上维护,每一次由负变正在线段树上会经过$O(logn)$层。

效率$O(logn)$。

其他的维护一下区间负数的个数什么的就可以搞了。

一遍AC爽

 #include <cstdio>
#include <cstring>
#include <algorithm> #define l(x) ch[x][0]
#define r(x) ch[x][1]
#define N 100010
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3fLL using namespace std; struct edge{
int x,to;
}E[N<<]; int n,m,totE;
int g[N]; inline int Abs(int x){
if(x<) return -x;
return x;
} inline void ade(int x,int y){
E[++totE]=(edge){y,g[x]}; g[x]=totE;
} namespace Segtree{
int tot;
int ch[N<<][];
int totf[N<<],siz[N<<];
LL maxf[N<<],sumv[N<<],addv[N<<]; void push(int x){
if(!l(x)||!addv[x]) return;
addv[l(x)]+=addv[x];
sumv[l(x)]+=addv[x]*(LL)(siz[l(x)]-*totf[l(x)]);
maxf[l(x)]+=addv[x];
addv[r(x)]+=addv[x];
sumv[r(x)]+=addv[x]*(LL)(siz[r(x)]-*totf[r(x)]);
maxf[r(x)]+=addv[x];
addv[x]=;
} void up(int x){
if(!l(x)) return;
sumv[x]=sumv[l(x)]+sumv[r(x)];
maxf[x]=max(maxf[l(x)],maxf[r(x)]);
totf[x]=totf[l(x)]+totf[r(x)];
} void change(int x,int l,int r,int ql,int qr,int qv){
push(x);
if(ql<=l&&r<=qr&&maxf[x]+qv<){
addv[x]+=qv;
sumv[x]+=qv*(LL)(siz[x]-*totf[x]);
maxf[x]+=qv;
}
else if(l==r){
sumv[x]=qv-sumv[x];
addv[x]=;
maxf[x]=-INF;
totf[x]=;
}
else{
int mid=(l+r)>>;
if(ql<=mid) change(l(x),l,mid,ql,qr,qv);
if(mid<qr) change(r(x),mid+,r,ql,qr,qv);
up(x);
}
} LL ask(int x,int l,int r,int ql,int qr){
push(x);
if(ql<=l&&r<=qr){
return sumv[x];
}
int mid=(l+r)>>;
LL ans=;
if(ql<=mid) ans+=ask(l(x),l,mid,ql,qr);
if(mid<qr) ans+=ask(r(x),mid+,r,ql,qr);
up(x);
return ans;
} int build(int src[],int l,int r){
int x=++tot;
siz[x]=r-l+;
if(l==r){
sumv[x]=Abs(src[l]);
addv[x]=;
if(src[l]>=) maxf[x]= -INF;
else maxf[x]=src[l];
totf[x]= (src[l]<) ? :;
return x;
}
int mid=(l+r)>>;
l(x)=build(src,l,mid);
r(x)=build(src,mid+,r);
up(x);
return x;
}
} #define p E[i].x int tott;
int L[N],a[N],fa[N],pos[N],c[N],d[N],siz[N],h[N],top[N];
bool v[N]; void dfs(int x){
v[x]=; siz[x]=; h[x]=;
for(int i=g[x];i;i=E[i].to)
if(!v[p]){
fa[p]=x;
d[p]=d[x]+;
dfs(p);
siz[x]+=siz[p];
if(siz[p]>siz[h[x]])
h[x]=p;
}
} void cut(int x,int ft){
L[x]=++tott; c[tott]=a[x]; pos[tott]=x; top[x]=ft;
if(h[x]) cut(h[x],ft);
for(int i=g[x];i;i=E[i].to)
if(p!=fa[x]&&p!=h[x])
cut(p,p);
} void change(int x,int y,int v){
int f1=top[x],f2=top[y];
while(f1!=f2){
if(d[f1]<d[f2]) swap(f1,f2),swap(x,y);
Segtree::change(,,n,L[f1],L[x],v);
x=fa[f1]; f1=top[x];
}
if(L[x]>L[y]) swap(x,y);
Segtree::change(,,n,L[x],L[y],v);
} LL ask(int x,int y){
int f1=top[x],f2=top[y];
LL ans=;
while(f1!=f2){
if(d[f1]<d[f2]) swap(f1,f2),swap(x,y);
ans+=Segtree::ask(,,n,L[f1],L[x]);
x=fa[f1]; f1=top[x];
}
if(L[x]>L[y]) swap(x,y);
ans+=Segtree::ask(,,n,L[x],L[y]);
return ans;
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
int cmd,x,y;
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
ade(x,y); ade(y,x);
}
d[]=;
dfs(); cut(,);
Segtree::build(c,,n);
for(int i=;i<=m;i++){
int v;
scanf("%d%d%d",&cmd,&x,&y);
if(cmd==){
scanf("%d",&v);
change(x,y,v);
}
else printf("%lld\n",ask(x,y));
}
return ;
}

BZOJ[4127] Abs的更多相关文章

  1. bzoj 4127: Abs 树链剖分

    4127: Abs Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 11  Solved: 5[Submit][Status][Discuss] Des ...

  2. BZOJ 4127 Abs 解题报告

    这个题感觉很厉害的样子.. 首先我们注意到一点:每次加的 $d$ 都是非负的. 那么就说明一个数只可能从负数变成非负数并且只会变一次. 所以我们就可以暴力地去改变一个数的正负情况. 然后我们就可以用树 ...

  3. BZOJ 4127: Abs (树链剖分 线段树求区间绝对值之和 带区间加法)

    题意 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d(d>=0) 2 u v 表示询问路径 (u,v) 上点权绝对值的和 分析 绝对值之和不好处理,那么我们开 ...

  4. bzoj 4127 线段树维护绝对值之和

    因为d>=0,所以一个位置的数只会单调不降并且只会有一次穿过0. 用这个性质,我们我可在线段树中记录正数负数的个数和和,以及最大的负数以及答案. 修改操作:如果当前最大负数+d<=0,那么 ...

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

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

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]

    BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1655  Solved: 798[Submit][S ...

  8. 【BZOJ】【2648】SJY摆棋子&【BZOJ】【2716】【Violet 3】天使玩偶

    KD-Tree 传说中的kd树...前去膜拜了一下……写道模板题>_< 写kdtree的一些感想: 插入的时候是像可持久化线段树一样直接在最后开新节点,然后更新它所在的块.. 然而其实也是 ...

  9. 【BZOJ】【3210】花神的浇花集会

    曼哈顿距离与切比雪夫距离 QAQ蒟蒻并不知道切比雪夫距离是什么……并不会做这道题…… 去膜拜了PoPoQQQ大爷的题解: 题目大意:给定平面上的n个点,求一个点到这n个点的切比雪夫距离之和最小 与31 ...

随机推荐

  1. VC++下编译Libgeotiff(含Libtiff)

    转自原文Win10+VC++下编译Libgeotiff(含Libtiff)详细图文教程 GeoTiff是包含地理信息的一种Tiff格式的文件.Libgeotiff就是一个操作GeoTiff文件的库.同 ...

  2. 如何使用NSOperations和NSOperationQueues 第二部分

    这篇文章还可以在这里找到 英语 以下是对上面代码的注解: 导入PhotoRecord.h文件,这样你就可以在下载成功后,单独地设置PhotoRecord变量的图片属性(image property). ...

  3. Docker 基础底层架构浅谈

    docker学习过程中,免不了需要学习下docker的底层技术,今天我们来记录下docker的底层架构吧! 从上图我们可以看到,docker依赖于linux内核的三个基本技术:namespaces.C ...

  4. 【Todo】【读书笔记】Linux高性能服务器编程

    在读 /Users/baidu/Documents/Data/Interview/服务器-检索端/<Linux高性能服务器编程.pdf> 其实之前读过,要面试了,需要温习. P260 So ...

  5. gulp 安装时一直提示缺少模块( Cannot find module 'gulp-load-plugins')

    我们要考虑两种情况? 1. 本地安装和全局安装gulp npm i -g gulp && npm i --save-dev gulp 2.新建package.json,然后手动填写缺少 ...

  6. 在windows Server 2008 R2server上使用infopath不能将表单公布到sharepoint server的问题处理。

    在server 2008 R2 中.你将做好的表单公布到Sharepoint 时候会报错: 这个情况在client是2008 R2 Server 就会出现这个结果. 在角色中启用桌面体验就可以

  7. c++面试题目(3)

    这些东西有点烦,有点无聊.如果要去C++面试就看看吧.几年前网上搜索的.刚才看到,就整理一下,里面有些被我改了,感觉之前说的不对或不完善. 1.求下面函数的返回值( 微软) int func(x)  ...

  8. 完美解决android显示gif

    今天是周5啊.纠结了一天.android显示gif,没该控件 网上找开源项目 找到个viewgif.该作者在各大站点都在推荐自己的项目...好吧.用下吧. . . . 结果呢: 图片略微一大就 内存溢 ...

  9. AptitudeSystem 2.0

    AptitudeSystem 2.0(2017-03-07) 描写叙述:Windows内核研究辅助工具 支持的系统:Windows 7.Windows 8.Windows 8.1.Windows 10 ...

  10. MapReduce算法形式四:mapjoin

    案例四:mapjoin(对个map共同输入,一个reduce) 这个方法主要解决的是,几个表之间的比较,类似于数据库的内外连接,还有一些左右连接之类的,简而言之就是,A表没有的B表有,B表有的A没有或 ...