好像没有什么高级数据结构能够很高效地实现这个东西;

那就上万能的分块,我们用一些数形结合的思想,把下标看成横坐标,前缀和的值看成纵坐标;

给区间内每个数都加k相当于相邻两点的斜率都加上k;

这种东西我们可以考虑用凸包来维护,因为根据凸包的几何意义,显然最值点在凸包上;

根据凸包的构造方式,相邻两点的斜率都加上k,在凸包中的点集是不变的,这就很好了;

每次二分出斜率为零的地方就好了;

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf=1e16;
const int maxn=;
int bo,tu[][],siz[],pos[maxn];
//fir是他被包含在某一个区间加中时,对这个块的贡献;arr时不包含;d是这个块被区间加了多少;
int m,sta[],top,n,cnt;
ll h[maxn],fir[],arr[],d[];
inline double xl(int x,int y){return double(h[y]-h[x])/double(y-x);}
//good
void build(int x){//在x这一块中构造凸包
int be=(x-)*bo+,en=min(x*bo,n);
top=;sta[++top]=be;
for(int i=be+;i<=en;++i){
while(top>=&&xl(sta[top-],sta[top])<xl(sta[top-],i))top--;
sta[++top]=i;
}
sta[]=;sta[top+]=n+;
siz[x]=top;
for(int i=;i<=top+;++i)tu[x][i]=sta[i];
}
//
//good
void pushdown(int x){
ll tmp=fir[x];
int be=(x-)*bo+,en=min(x*bo,n);
for(int i=be;i<=en;++i){
h[i]+=tmp;tmp+=d[x];h[i]+=arr[x];
}
fir[x]=d[x]=arr[x]=;
}
//
//good
ll cal(int p){
if(p==||p==n+)return -inf;
int x=pos[p];
return h[p]+fir[x]+d[x]*(p-((x-)*bo+))+arr[x];
}
//
//good
ll fin(int x){
int l=,r=siz[x];
ll h1,h2,h3;
while(l<=r){
int mid=(l+r)>>;
h1=cal(tu[x][mid-]),h2=cal(tu[x][mid]),h3=cal(tu[x][mid+]);
if(h1<h2&&h2<h3)l=mid+;
else {
if(h1>h2&&h2>h3)r=mid-;
else{return h2;}
}
}
}
//
int main(){
cin>>n;
bo=(int)sqrt(n);
cnt=(n-)/bo+;
h[]=h[n+]=-inf;
for(int i=;i<=n;++i){
scanf("%lld",&h[i]);
}
for(int i=;i<=n;++i){
h[i]+=h[i-];
}
for(int i=;i<=n;++i){
pos[i]=(i-)/bo+;
}
for(int i=;i<=cnt;++i)build(i);
cin>>m;
int op,x,y,l,r;
ll k,tmp,ans;
for(int i=;i<=m;++i){
scanf("%d%d%d",&op,&x,&y);
if(!op){
scanf("%lld",&k);
l=pos[x];r=pos[y];
tmp=k*(l*bo+-x+);
for(int i=l+;i<=r-;++i){
fir[i]+=tmp;d[i]+=k;
tmp+=bo*k;
}
pushdown(l);
tmp=k;
for(int i=x;i<=min(y,min(l*bo,n));++i)
h[i]+=tmp,tmp+=k;
build(l);
pushdown(r);
if(l!=r){
tmp=k*((r-)*bo-x+);
for(int i=(r-)*bo+;i<=y;++i){
h[i]+=tmp;tmp+=k;
}
}
tmp=k*(y-x+);
for(int i=y+;i<=min(r*bo,n);++i)h[i]+=tmp;
build(r);
for(int i=r+;i<=cnt;++i)arr[i]+=tmp;
}
else{
l=pos[x];r=pos[y];ans=-inf;
for(int i=l+;i<r;++i)
ans=max(ans,fin(i));
for(int i=x;i<=min(y,min(l*bo,n));++i){
ans=max(ans,cal(i));
}
if(l!=r){
for(int i=(r-)*bo+;i<=y;++i){
ans=max(ans,cal(i));
}
}
printf("%lld\n",ans);
}
}
system("pause");
return ;
}

bzoj2388(分块 凸包)的更多相关文章

  1. 2019.01.20 bzoj2388: 旅行规划(分块+凸包)

    传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi​)答案一定会在凸包上 ...

  2. BZOJ2388:旅行规划(travel)——分块凸包

    题目 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路 ...

  3. BZOJ2388: 旅行规划(分块 凸包)

    题意 题目链接 Sol 直接挂队爷的题解了 分块题好难调啊qwq #include<bits/stdc++.h> #define LL long long using namespace ...

  4. BZOJ 2388: 旅行规划 [分块 凸包 等差数列]

    传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...

  5. 「BZOJ2388」旅行规划

    传送门 分块+凸包 求出前缀和数组s 对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列.r~n加上k*(r-l+1). 分块之后对每一块维护两个标记,一个记录它加的等差数 ...

  6. 旅行规划(travel)

    题目描述 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 nnn 个最著名的经典连接起来,让游客可以通过火车从 ...

  7. ZROI 19.07.28 序列数据结构/jk

    写在前面 dls:"我不会数据结构,但是APIO的数据结构场我写了,还是蛮简单的." T1 CF643G Sol: 有一个\(O(n\log^2n)\)的做法:假设将区间排好序,取 ...

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

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

  9. CF573E Bear and Bowling 贪心、分块、凸包

    传送门 题解搬运工++ 先证明一个贪心做法的正确性:做以下操作若干次,每一次考虑选择没有被选到答案序列中的数加入到答案序列中对答案的贡献,设第\(i\)个位置的贡献为\(V_i\),如果最大的贡献小于 ...

随机推荐

  1. [z] Git pull 强制覆盖本地文件

    git fetch --all git reset --hard origin/master git pull git fetch 只是下载远程的库的内容,不做任何的合并 git reset 把HEA ...

  2. Event 事件

    事件是建立在委托的基础之上的. http://www.cnblogs.com/lystory/p/5085786.html public class 事件参数 { public 事件参数(string ...

  3. virtaulbox docker虚拟机使用主机代理shandowsocks

    1.virtaulbox 配置NatNetwork File->Preference->network->add new nat network 2.virtaulbox 虚拟机配置 ...

  4. url中含有%

    Server.UrlEncode(“参数”)也可以使用javascript 的编码方式href="页面?name=encodeURI("参数")传送页代码编码 接收页代码 ...

  5. L1-025 正整数A+B(15)(思路+测试点分析)

    L1-025 正整数A+B(15 分) 题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000].稍微有点麻烦的是,输入并不保证是两个正整数. 输入格式: 输入在一行给出A和B, ...

  6. 修改别人写的Hibernate数据库操作代码

    最近正在维护别人写的一个关于Hibernate操作数据库的项目,在运行测试的时候(向表中插入记录),报了一个错误:cannot insert a null into column(XXX字段名,下文统 ...

  7. 利用gulp搭建less编译环境

       什么是less? 一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, ...

  8. Ubuntu12.04软件安装指南

    更新升级源 首先编辑软件源,在终端输入下面命令: sudo gedit /etc/apt/sources.list 较快速的升级源有163,台湾源,科大源,搜狐源等,大家将新的升级源全部覆盖原文件so ...

  9. UI设计教程分享:电商网页页面设计常见表现手法

    1.手绘插画  场景.人物以及加上故事的创意绘画 会给人梦幻若隐若现的感觉,留下深刻的印象,适合做活动页面以及宣传自已的品牌 2.简约 颜色少于三色,背景以明度偏低的颜色为主,在信息大爆炸的时代,我们 ...

  10. samtools flagstat

    samtools flagstat命令简介: 统计输入文件的相关数据并将这些数据输出至屏幕显示.每一项统计数据都由两部分组成,分别是QC pass和QC failed,表示通过QC的reads数据量和 ...