假设所有操作都是对整个序列的。考虑每个子区间,区间和与其被加的值构成一次函数关系。最大子段和相当于多个子区间取最大值,答案显然就在这些一次函数构成的下凸壳上。如果预处理出凸壳,只要在凸壳上暴力跳就可以回答询问了,因为加的都是正数,并且斜率不同的一次函数数量是O(n)的。暴力建凸壳的复杂度是O(n2)的。

  那么考虑分块。每个块预处理出凸壳。区间加时,对于整块在凸壳上暴跳,零散部分暴力重构。查询时合并区间,类似于单点加的线段树做法,维护块内最大前缀和、最大后缀和。块大小取n1/3时最优。

  造凸壳写挂调了1h,退役了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 50010
#define NUM 2000
#define BLOCK 100
#define inf 10000000000000000ll
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,pos[N],num,block;
ll a[N],tmp[N],PRE[N],SUF[N];
struct line
{
ll k,b;
ll f(ll x){return k*x+b;}
};
ll cross(line x,line y){return (x.b-y.b-)/(y.k-x.k)+;}
struct hull
{
line a[BLOCK];int cnt,cur;
void ins(line x){while (cnt&&x.b>=a[cnt].b||cnt>&&x.f(cross(a[cnt],a[cnt-]))>a[cnt].f(cross(a[cnt],a[cnt-]))) cnt--;a[++cnt]=x;}
void clear(){cnt=,cur=,ins((line){,});}
void jump(ll x){while (cur<cnt&&a[cur].f(x)<a[cur+].f(x)) cur++;}
ll get(ll x){return a[cur].f(x);}
};
struct data
{
hull pre,suf,seq;int L,R;ll lazy,sum;
void build()
{
for (int i=L;i<=R;i++) a[i]+=lazy;lazy=;
sum=;for (int i=L;i<=R;i++) sum+=a[i];
ll x=;pre.clear();
for (int i=L;i<=R;i++) pre.ins((line){i-L+,x+=a[i]});
x=;suf.clear();
for (int i=R;i>=L;i--) suf.ins((line){R-i+,x+=a[i]});
seq.clear();
for (int k=;k<=R-L+;k++)
{
ll s=-inf;x=;for (int i=L;i<=L+k-;i++) x+=a[i];
for (int i=L+k-;i<=R;i++) s=max(s,x),x+=a[i+]-a[i-k+];
seq.ins((line){k,s});
}
}
void add(int x){sum+=1ll*(R-L+)*x,lazy+=x,pre.jump(lazy),suf.jump(lazy),seq.jump(lazy);}
ll maxpre(){return pre.get(lazy);}
ll maxsuf(){return suf.get(lazy);}
ll maxseq(){return seq.get(lazy);}
}f[NUM];
ll getseq(int l,int r)
{
ll s=,ans=;
for (int i=l;i<=r;i++)
{
s+=tmp[i];
if (s<) s=;
ans=max(ans,s);
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5089.in","r",stdin);
freopen("bzoj5089.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();block=*pow(n,1.0/)+;num=(n-)/block+;
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=num;i++)
{
f[i].L=f[i-].R+,f[i].R=min(n,f[i].L+block-);
for (int j=f[i].L;j<=f[i].R;j++) pos[j]=i;
f[i].build();
}
while (m--)
{
char c=getc();
if (c=='A')
{
int l=read(),r=read(),x=read();
if (pos[l]==pos[r])
{
for (int i=l;i<=r;i++) a[i]+=x;
f[pos[l]].build();
}
else
{
for (int i=pos[l]+;i<pos[r];i++) f[i].add(x);
for (int i=l;i<=f[pos[l]].R;i++) a[i]+=x;f[pos[l]].build();
for (int i=f[pos[r]].L;i<=r;i++) a[i]+=x;f[pos[r]].build();
}
}
else
{
int l=read(),r=read();
if (pos[l]==pos[r])
{
for (int i=l;i<=r;i++) tmp[i]=a[i]+f[pos[l]].lazy;
printf(LL,getseq(l,r));
}
else
{
for (int i=l;i<=f[pos[l]].R;i++) tmp[i]=a[i]+f[pos[l]].lazy;
for (int i=f[pos[r]].L;i<=r;i++) tmp[i]=a[i]+f[pos[r]].lazy;
ll ans=max(getseq(l,f[pos[l]].R),getseq(f[pos[r]].L,r)),s;
for (int i=pos[l]+;i<pos[r];i++) ans=max(ans,f[i].maxseq());
for (int i=pos[l];i<=pos[r];i++) PRE[i]=SUF[i]=;
s=;for (int i=f[pos[l]].R;i>=l;i--) s+=tmp[i],SUF[pos[l]]=max(SUF[pos[l]],s);
s=;for (int i=f[pos[r]].L;i<=r;i++) s+=tmp[i],PRE[pos[r]]=max(PRE[pos[r]],s);
for (int i=pos[l]+;i<pos[r];i++) SUF[i]=max(f[i].maxsuf(),SUF[i-]+f[i].sum);
for (int i=pos[r]-;i>pos[l];i--) PRE[i]=max(f[i].maxpre(),PRE[i+]+f[i].sum);
for (int i=pos[l];i<pos[r];i++) ans=max(ans,SUF[i]+PRE[i+]);
printf(LL,ans);
}
}
}
return ;
}

BZOJ5089 最大连续子段和(分块)的更多相关文章

  1. bzoj5089 最大连续子段和 分块+复杂度分析+凸包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5089 题解 本来打算迟一点再写这个题解的,还有一个小问题没有弄清楚. 不过先写一下存个档吧. ...

  2. 【bzoj5089】最大连续子段和 分块+单调栈维护凸包

    题目描述 给出一个长度为 n 的序列,要求支持如下两种操作: A  l  r  x :将 [l,r] 区间内的所有数加上 x : Q  l  r : 询问 [l,r] 区间的最大连续子段和. 其中,一 ...

  3. BZOJ5089: 最大连续子段和

    维护一个序列支持以下操作:区间加,区间求最大子段和.n<=50000,m<=50000. 我TM再也不写分块了... 先分块,对于块整体加的操作,假设块里面有若干二元组(x,y),表示一个 ...

  4. HDOJ-1003 Max Sum(最大连续子段 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=1003 给出一个包含n个数字的序列{a1,a2,..,ai,..,an},-1000<=ai<=100 ...

  5. HDU 1003:Max Sum(DP,连续子段和)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  6. HPU 1007: 严格递增连续子段(贪心)

    1007: 严格递增连续子段 [模拟] 时间限制: 1 Sec 内存限制: 128 MB提交: 244 解决: 18 统计 题目描述 给定一个有NN个正整数组成的序列,你最多可以改变其中一个元素,可以 ...

  7. HDU 1003 最大连续子段和

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)M ...

  8. [题解](线段树最大连续子段和)POJ_3667_Hotel

    题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点 2.修改一个区间为0 实际上是维护最大连续子段和,原来也写过 大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护 ...

  9. JDOJ 2982: 最大连续子段和问题

    洛谷 P1115 最大子段和 洛谷传送门 JDOJ 2982: 最大连续子段和问题 JDOJ传送门 题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入格式 第一行是一个正整数NN, ...

随机推荐

  1. Altium 中异形焊盘异形封装的创建图文教程

    Altium 中异形焊盘异形封装的创建图文教程 一般不规则的焊盘被称为异型焊盘,典型的有金手指.大型的器件焊盘或者板子上需要添加特殊形状的铜箔(可以制作一个特殊封装代替). 如图27所示,此处我们以一 ...

  2. Jenkins自动化测试

    Jenkins自动化测试 一个持续集成的基本原则是构建应该是可验证的.你必须能够客观地确定一个特定的构建是否准备就绪构建过程的下一个阶段,最便捷的方式做到这一点是使用自动化测试.如果没有适当的自动化测 ...

  3. Python之元类详解

    一.引子 元类属于Python面向对象编程的深层魔法,99%的人都不得要领,一些自以为搞明白元类的人其实也是自圆其说,点到为止,从队元类的控制上来看就破绽百出,逻辑混乱: 二.什么是元类 一切源自于一 ...

  4. 在WebGL场景中管理多个卡牌对象的实验

    这篇文章讨论如何在基于Babylon.js的WebGL场景中,实现多个简单卡牌类对象的显示.选择.分组.排序,同时建立一套实用的3D场景代码框架.由于作者美工能力有限,所以示例场景视觉效果可能欠佳,本 ...

  5. 比较undefined和“undefined”

    说实话,它们之间的区别挺明显的,我们一般认为undefined是JavaScript提供的一个“关键字”,而“undefined”却是一个字符串,只是引号的内容和undefined一样. undefi ...

  6. docker 安装vim

    执行以下命令 apt-get update apt-get install vim

  7. 马赛克是否无法逆转?Python简单消除,看片无忧!

    图片水印,轻松去除 前段时间玩过了全民K歌,不知道大家是否玩过,还是做得挺好的,就我这嗓子都能唱出张学友的味道,其中更是有消除噪声的功能,就是朋友们都在吃鸡大叫,我在旁边唱歌依然不受影响. 既然声音可 ...

  8. No.1100_第九次团队会议

    在今天项目有了新的突破,大家的情绪明显高涨了一些,一改往日的颓丧.但是仍然还有很多功能没有完善,于是大家相互交流了一下自己的进度,列出还没有完善的部分,有些困难的部分一时解决不了,我们决定多人合作来解 ...

  9. Linux基础入门--06

    简单的文本处理 实验介绍 这一节我们将介绍这几个命令:tr.col.join.paste 1.tr: -d:删除和set1匹配的字符,不是全词匹配也不是按字符顺序匹配 -s:除去指定的连续并重复的字符 ...

  10. 05慕课网《进击Node.js基础(一)》HTTP概念进阶(同步/异步)

    HTTP模块介绍 支持http协议的更多特性 不缓存请求和响应 API比较底层处理流相关,信息解析 HTTP相关概念 回调 将函数作为参数传到执行函数中,参数函数在执行函数中嵌套执行 function ...