题目: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. SystemTap使用技巧 1 - 4 非常重要

    http://blog.csdn.net/wangzuxi/article/details/42849053

  2. HDU 1501

    Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  3. PCA主成分分析Python实现

    作者:拾毅者 出处:http://blog.csdn.net/Dream_angel_Z/article/details/50760130 Github源代码:https://github.com/c ...

  4. 浏览器g.xxx333xxx.com 跳转2345问题解决方法

    近期升级windows10系统我,我顺手在浏览器输入"windows10"激活keyword,下载了小马激活工具进行了激活.例如以下图. 下载安装后.浏览器每次打开强制跳转到234 ...

  5. CF 535c Tavas and Karafs

    Tavas and Karafs Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u S ...

  6. php 封装memcache类

    <?php /*  * memcache类   */ class Memcacheds{     //声明静态成员变量     private static $m = null;     pri ...

  7. PandoraBox 支持3G无线上网卡(电信卡3G卡)(三)

    笔者采用的是华为EC122无线上网卡 一:编辑/etc/modules.d/60-usb-serial usbserial vendor=0x12d1   product=0x1505 二:编辑/et ...

  8. add time to file name

    add time to file name echo 123 > $(date +"%Y%m%d_%H%M%S").now; mv /mnt/mongodb_data/dat ...

  9. char* strcpy( char* dest, const char* src ), int binary_search(int *arr, int key, int n), 可能的实现

    #include <stdio.h> char* stringCopy( char* dest, const char* src ) { size_t i = 0; while (dest ...

  10. 对 block 内存管理的一些看法

    首先交代一下retain cycle ,和 产生retain cycle后我们应该怎么处理. 1.retain cycle在block中是极易产生,block就是一段可以灵活使用的代码,你可以把它当做 ...