题目: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. Spring启动流程

    首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境: 其次,在web.xm ...

  2. Git checkout on a remote branch does not work

    I believe this occurs when you are trying to checkout a remote branch that your local git repo is no ...

  3. 创建pycharm项目时项目解释器的选择

    创建pycharm项目时项目解释器的选择 Location下面有一个Project Interpreter: Python3.6,打开之后有两个选项, 如果选择了第一个,项目创建之后,在cmd中pip ...

  4. linux 环境 php 链接 sqlserver 2008

    说明 由于业务需要 在 linux 系统下的 PHP 环境中 要链接 sqlserver2008 数据库 . 添加PHP 链接数据库扩展 php-mssql dockerfile FROM hub.0 ...

  5. html中&lt;li&gt;&lt;/li&gt;中使用&lt;br&gt;和&lt;li&gt;&lt;/li&gt;外面使用&lt;br&gt;

    </pre><pre> <!DOCTYPE html> <html> <head> <meta http-equiv="Co ...

  6. android 4.4以上能够实现的沉浸式状态栏效果

    仅仅有android4.4以及以上的版本号才支持状态栏沉浸效果 先把程序执行在4.4下面的手机上,看下效果: 在4.4以上的效果: watermark/2/text/aHR0cDovL2Jsb2cuY ...

  7. java开始到熟悉72-76

    本次内容:异常机制 1.为什么需要异常 2.异常 3.error类 4.exception类 5.exception类中的unchecked exception 举例: 6.常用异常处理方法 a.tr ...

  8. 如何理解pca和svd的关系?

    主成分分析和奇异值分解进行降维有何共同点? 矩阵的奇异值分解 当矩阵不是方阵,无法为其定义特征值与特征向量,可以用一个相似的概念来代替:奇异值. 通常用一种叫奇异值分解的算法来求取任意矩阵的奇异值: ...

  9. HDOJ1006

    #include <cstdio>#include <algorithm>using namespace std;const double UB=43200;const dou ...

  10. 杭电 1596 find the safest road (最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=1596 这道题目与杭电2544最短路的思想是一样的.仅仅只是是把+改成了*,输入输出有些不一样而已. find t ...