传送门

题意:

区间加和询问一段区间内整体前缀和的最大值


刚才还在想做完这道题做一道区间加等差数列结果发现这道就是....

唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!!

线段树没法搞吧....分块!

每个块维护整体加标记,首项,公差

修改的时候:

左面不完整的块下放标记暴力重构;

中间的整块打标记;

右面不完整的块也是下放标记暴力重构,注意这个地方$r$之外的部分也要更新!

右面完整的块也要打标记!

怎么查询呢?

左右不完整的块暴力查询

中间的整块,可以发现我们每次修改的只有公差会造成影响,类似于斜率,凸包的形状不会改变(斜率的相对大小不会改变),所以维护一个凸包,查询时三分就行了

其实我现在还不会三分就去黄学长哪里抄了一个奇怪的东西

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+,M=;
const ll INF=1e18;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,Q,op,x,y; ll a[N];
struct _blo{int l,r;}b[M];
int block,m,pos[N];
inline void ini(){
block=sqrt(n); m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+;
for(int i=;i<=m;i++) b[i].l=(i-)*block+ , b[i].r=i*block;
b[m].r=n;
} struct ConvexHull{
int a[M],n;
int& operator [](int x){return a[x];}
}con[M];
int st[N]; struct Block{
inline double slope(int i,int j){return (double)(a[i]-a[j])/(i-j);}
void Set(int x){
int top=;
for(int i=b[x].l ; i<=b[x].r ; i++){
while(top> && slope(i,st[top-])>=slope(st[top],st[top-]) ) top--;
st[++top]=i;
}
for(int i=;i<=top;i++) con[x][i]=st[i];
con[x].n=top; con[x][]=con[x][top+]=;
} ll f[M],d[M],add[M];
void pushDown(int x){
ll now=f[x];
for(int i=b[x].l ; i<=b[x].r ; i++) a[i]+=now+add[x],now+=d[x];
f[x]=d[x]=add[x]=;
} void Add(int l,int r,ll v){
int pl=pos[l],pr=pos[r];
ll now=;
if(pl==pr){
pushDown(pl);
for(int i=l;i<=r;i++) now+=v,a[i]+=now;
for(int i=r+ ; i<=b[pr].r ; i++) a[i]+=now;
Set(pl); for(int i=pr+;i<=m;i++) add[i]+=now;
}else{
pushDown(pl);
for(int i=l ; i<=b[pl].r ; i++) now+=v,a[i]+=now;
Set(pl); for(int i=pl+;i<pr;i++) now+=v,f[i]+=now,d[i]+=v,now+=v*(block-); pushDown(pr);
for(int i=b[pr].l ; i<=r ; i++) now+=v,a[i]+=now;
for(int i=r+ ; i<=b[pr].r ;i++) a[i]+=now;
Set(pr); for(int i=pr+;i<=m;i++) add[i]+=now;
}
} inline ll cal(int x){
if(x==) return -INF;//!!!!!
int t=pos[x];
return a[x]+add[t] + f[t]+d[t]*(x-b[t].l) ;
}
ll Bin(int x){
int l=,r=con[x].n;
while(l<=r){
int mid=(l+r)>>;
ll a=cal(con[x][mid-]),b=cal(con[x][mid]),c=cal(con[x][mid+]);
if(a<b&&b<c) l=mid+;
else if(a>b&&b>c) r=mid-;
else return b;
}
return ;
}
ll Que(int l,int r){
int pl=pos[l],pr=pos[r];
ll re=-INF;
if(pl==pr)
for(int i=l;i<=r;i++) re=max(re,cal(i));
else{
for(int i=l ; i<=b[pl].r ; i++) re=max(re,cal(i));
for(int i=b[pr].l ; i<=r ; i++) re=max(re,cal(i));
for(int i=pl+;i<pr;i++) re=max(re,Bin(i));
}
return re;
}
}B; int main(){
freopen("in","r",stdin);
n=read(); ini();
for(int i=;i<=n;i++) a[i]=read()+a[i-];
for(int i=;i<=m;i++) B.Set(i);
Q=read();
while(Q--){
op=read();x=read();y=read();
if(op==) B.Add(x,y,read());
else printf("%lld\n",B.Que(x,y));
}
}

BZOJ 2388: 旅行规划 [分块 凸包 等差数列]的更多相关文章

  1. @bzoj - 2388@ 旅行规划

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...

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

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

  3. BZOJ 2388--旅行规划(分块&单调栈&二分)

    2388: 旅行规划 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 405  Solved: 118[Submit][Status][Discuss] ...

  4. 「BZOJ2388」旅行规划

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

  5. 旅行规划(travel)

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

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

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

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

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

  8. bzoj 4501: 旅行 01分数规划+概率期望dp

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4501 题解: 首先我们不考虑可以删除边的情况下,如何计算期望边数. 然后我们发现这是个有 ...

  9. BZOJ.4942.[NOI2017]整数(分块)

    BZOJ 洛谷 UOJ 可能是退役之前最后一个BZOJ rank1了? 参考这里. 如果没有减法,对一个二进制数暴力进位,均摊复杂度是\(O(1)\)的(要进\(O(n)\)次位就至少需要\(O(n) ...

随机推荐

  1. QT 操作 excel 教程

    前言:环境 win7 64位,QT4.8.5,QT Creator 在 .pro 文件中加入语句"CONFIG+=qaxcontainer"; 源码如下: //main.cpp # ...

  2. UEP-标签

    这里的标签都是常用不好理解的: formatfunc="showFormatNumer" 显示数字在页面上 ockedcolumnnum="6" 几列是不动的 ...

  3. the server responded with a status of 414 (Request-URI Too Large)

    nginx 配置不当,前端ajax调用报错: the server responded with a status of 414 (Request-URI Too Large) 浏览器F12报错如下: ...

  4. 在form里面,放了四个UEditor,怎么在后台分别获取它们值

    1) 默认情况下提交到后台的表单名称是 "editorValue",在editor_config.js中可以配置,参数名为textarea. 2) 可以在容器标签(即script标 ...

  5. 教你搭建你自己的Git服务器

    http://lib.csdn.net/article/git/50086 导读 现在我们将要学习如何搭建 git 服务器,如何编写自定义的 Git 钩子来在特定的事件触发相应的动作(例如通知),或者 ...

  6. 版本控制——TortoiseSVN (1)安装与配置

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  7. MYsql优化where子句

    该部分讨论where子句的优化,不仅select之中,相同的优化同样试用与delete 和update语句中的where子句: 1: 移去不必要的括号: ((a AND b) AND c OR ((( ...

  8. CCF系列之矩阵(201512-5)

    试题名称: 矩阵 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 创造一个世界只需要定义一个初状态和状态转移规则. 宏观世界的物体运动规律始终跟物体当前的状态有关,也就是说只要 ...

  9. Number()和new Number()的区别以及一种简单实现

    看MDN Beginners文档的时候注意到了这种用法 var n1 = Number(123); , 冒出的第一个疑问就是和 var n2 = new Number(123); 有什么区别呢? 首先 ...

  10. subList ArrayList LinkedList

    List<E> subList(int fromIndex,int toIndex) 该方法返回原有集合从fromIndex 到 toIndex之间一部分数据,组成一个新的集合,这两个集合 ...