题目: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. 高效的MySQL的批插入 BULK INSERT

    原文:http://www.open-open.com/code/view/1453702496573 MySQL的批插入 BULK INSERT和load data的速度差不多,并且可靠. 语法如下 ...

  2. kafka-0.8.1.1总结

    文件夹 一.         基础篇 1.     开篇说明 2.     概念说明 3.     配置说明 4.     znode分类 5.     kafka协议分类 6.     Kafka线 ...

  3. php 中函数获取可变参数的方法, 这个语法有点像 golang 语言中的

    原文呢:http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict Onl ...

  4. Mqtt协议IOS端移植3

    ServerMqFramework.h #import "MqttFramework.h" @interface ServerMqFramework : MqttFramework ...

  5. NGUI UIScrollView - 大量item子项的性能优化

    一.当UIScrollView的以下的包括的子项太多(二三十个之上)时.它的滚动就会变的有些卡不流畅,尤其是在手机上. 对些网上也有非常多的优化它的相关,以下是我的一个优化: 1.将在超出裁剪框的一个 ...

  6. Windows-速度优化的几个方面

    One. Win+R - > cmd- > msconfig 禁用不需要的启动项! Two. 关闭一些视觉选项 Three. 设置应用启动快捷键

  7. SQL ORDER BY 关键字

    SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集进行排序. SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序. ORDER BY ...

  8. 【转载】C#中的泛型

    1.1 C#中的泛型 .Net 1.1版本最受诟病的一个缺陷就是没有提供对泛型的支持.通过使用泛型,我们可以极大地提高代码的重用度,同时还可以获得强类型的支持,避免了隐式的装箱.拆箱,在一定程度上提升 ...

  9. php使用魔法函数和不使用魔法函数比较

    /** * use magic 0.31868386268616s * not use magic 0.11876797676086s */ class Test { private $varstr ...

  10. hive cli 启动缓慢问题

    hive-0.13.1启动缓慢的原因 发现时间主要消耗在以下3个地方: 1. hadoopjar的时候要把相关的jar包上传到hdfs中(这里大概消耗5s,hive0.11一样,这个地方不太好优化) ...