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

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

给区间内每个数都加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. SSH Secure Shell链接Ubuntu报错Server responded "Algorithm negotiation failed"

    vim /etc/ssh/sshd_config Ciphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3 ...

  2. Java中的权限修饰符

    What:访问控制权限是可以设置代码的访问范围. Where:访问权限既可以修饰类中的属性,又可以修饰类中的方法,而public和default还可以修饰类. 在同一个java文件里,公有类有且仅有一 ...

  3. 基于稀疏表(Sparse Table)的RMQ(区间最值问题)

    在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...

  4. 隐马尔科夫_HMM

    有向图 抽象:λ代表输入:输入一个句子,λi表示句子中的每个字 O代表输出:[B词首/M词中/E词尾/S单独成词] max=maxP(O1 O2 On/ λ1 λ2 λn) 假设: (1)当前观察值只 ...

  5. h5页面适配iPhone X的方法

    一.原生适配iphoneX 原生适配很简单,查看机型图:   只要用 #define KIsiPhoneX ([UIScreen mainScreen].bounds.size.height>8 ...

  6. 【UI测试】--快捷键组合

  7. 对团队项目的NABCD的分析

    需求(N):我们的软件是面向广大想记录自己所爱动植物成长点滴的人.目前没有很好地软件,只有手机或者电脑上的笔记本和备忘录. 做法(A):我们的软件可以交流可以节约积累知识的时间,将记录从记事本中摘出来 ...

  8. java学习第四周

    这是暑假第四周,这周我继续学习了Java的基础知识. 了解到Java的类继承,学习到Java的接口的相关知识Java的每一个类都有且仅有一个直接父类,没有多重继承,但是接口可以继承多个,如果把接口看做 ...

  9. SQL语句备份和还原数据库

    1,使用SQL最简单备份,还原数据库 1 /* 备份 */ 2 backup database Test to disk='D:/Test.bak' 3 /* 还原 */ 4 restore data ...

  10. 2019.01.22 bzoj3333: 排队计划(逆序对+线段树)

    传送门 题意简述:给出一个序列,支持把ppp~nnn中所有小于等于apa_pap​的'扯出来排序之后再放回去,要求动态维护全局逆序对. 思路:我们令fif_ifi​表示第iii个位置之后比它大的数的个 ...