传送门

大意:给定一个序列,要求支持2种操作

1、区间加

2、询问区间lll~rrr内最大的一个前缀和


很显然如果我们把每个点的前缀和sumisum_isumi​以(i,sumi)(i,sum_i)(i,sumi​)列在二维平面上

询问就变成了求lll~rrr内的上凸包

由于线段树之类的无法维护

于是考虑分块维护上凸包

每次整块修改不会改变内部凸包

散块修改后暴力重构

由于我们记录的是一个前缀和

则区间加就变成了加一个等差数列

对rrr之后则是加一个值

所以维护一下firfirfir数列开头,deldeldel公差,addaddadd加

维护一下

复杂度O(nnlogn)O(n\sqrt n log_n)O(nn​logn​)

常数较小跑的比较快

#include<bits/stdc++.h>
using namespace std;
inline int read(){char ch=getchar();int res=0,f=1;while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();return res*f;
}
#define ll long long
const int N=100005;
const int M=350;
const ll inf=100000000000000;
int n,m,len,cnt,plc[N],l[M],r[M],num[M],stk[N],con[M][M];
ll sum[N],fir[M],del[M],add[M];
inline double slop(int x,int y){return (double)(sum[y]-sum[x])/(y-x);
}
inline ll calc(int x){if(x==0||x==n+1)return -inf;return sum[x]+fir[plc[x]]+del[plc[x]]*(x-l[plc[x]])+add[plc[x]];
}
inline void reset(int x){int top=0;stk[++top]=l[x];for(int i=l[x]+1;i<=r[x];i++){while(top>=2&&slop(stk[top-1],stk[top])<slop(stk[top-1],i))top--;stk[++top]=i;}num[x]=top;stk[++top]=n+1;for(int i=0;i<=top;i++)con[x][i]=stk[i];
}
inline void pushdown(int x){ll tmp=fir[x];for(int i=l[x];i<=r[x];i++){sum[i]+=tmp,tmp+=del[x],sum[i]+=add[x];}del[x]=add[x]=fir[x]=0;
}
inline void update(int x,int y,ll k){pushdown(plc[x]);ll tmp=k;for(int i=x;i<=min(y,r[plc[x]]);i++){sum[i]+=tmp,tmp+=k;}reset(plc[x]);for(int i=plc[x]+1;i<=plc[y]-1;i++){fir[i]+=tmp,del[i]+=k,tmp+=len*k;}pushdown(plc[y]);if(plc[x]!=plc[y]){for(int i=l[plc[y]];i<=y;i++){sum[i]+=tmp,tmp+=k;}}tmp-=k;//因为为了后面的计算所以每次加一个k,但在最后一个点的时候后面是不加的,所以要减去一个kfor(int i=y+1;i<=r[plc[y]];i++)sum[i]+=tmp;reset(plc[y]);for(int i=plc[y]+1;i<=cnt;i++)add[i]+=tmp;
}
inline ll find(int x){int l=1,r=num[x];ll a1,a2,a3;while(l<=r){int mid=(l+r)>>1;a1=calc(con[x][mid-1]),a2=calc(con[x][mid]),a3=calc(con[x][mid+1]);if(a1<a2&&a2<a3)l=mid+1;else if(a1>a2&&a2>a3)r=mid-1;else return a2;}
}
inline ll query(int x,int y){ll ans=-inf;for(int i=plc[x]+1;i<=plc[y]-1;i++){ans=max(ans,find(i));}for(int i=x;i<=min(y,r[plc[x]]);i++){ans=max(ans,calc(i));}if(plc[x]!=plc[y]){for(int i=l[plc[y]];i<=y;i++)ans=max(ans,calc(i));}return ans;
}
int main(){n=read();for(int i=1;i<=n;i++){sum[i]=sum[i-1]+read();}sum[0]=sum[n+1]=-inf;len=sqrt(n),cnt=(n-1)/len+1;for(int i=1;i<=n;i++)plc[i]=(i-1)/len+1;for(int i=1;i<=cnt;i++)l[i]=(i-1)*len+1,r[i]=i*len;for(int i=1;i<=cnt;i++)reset(i);m=read();for(int i=1;i<=m;i++){int op=read();if(op==0){int x=read(),y=read(),k=read();update(x,y,k);}else {int x=read(),y=read();cout<<query(x,y)<<'\n';}}
}

转载于:https://www.cnblogs.com/stargazer-cyk/p/10366343.html

【BZOJ2388】—旅行规划(分块+凸包)相关推荐

  1. 【分块】[LUOGU 旅行规划] 分块+二分+凸包优化

    题目: 题目链接:[LUOGU 旅行规划] 题解: (由于这个,,我竟然还去写了二维凸包的模板题作为练习,,,然而,一点用都没有,,,,) 先解释一下题面的意思:就是一个区间加的操作,再加上一个区间的 ...

  2. BZOJ2388 : 旅行规划

    考虑分块,每块维护两个标记$ts,td$. 那么对于块中一个位置$i$,它的实际值为$i\times td+ts+v_i$. 修改的时候,对于整块,直接打标记,对于零散的暴力修改,然后重构凸壳,时间复 ...

  3. BZOJ2388: 旅行规划

    http://www.lydsy.com/JudgeOnline/problem.php?id=2388 带区间加修改,求区间内的最大前缀和. 设sum[i]代表i的前缀和,tag[i][j]代表i到 ...

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

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

  5. CF436F Banners(分块/凸包/单调队列)

    CF436F Banners 首先有n个物品分别有ai和bi,然后定义价值为 c∗w+p∗(ai大于p且bi小于c的用户个数)c*w+p*(ai大于p且bi小于c的用户个数)c∗w+p∗(ai大于p且 ...

  6. @bzoj - 2388@ 旅行规划

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

  7. 离散数学图论旅行规划问题_《图论及其应用》(一)

    点击返回目录 一. 定义 1.1 图的基本概念 图或有序对或序偶(P1).有限图/平凡图/非平凡图/空图(P1).顶点数或阶数/边数/重数/重边/环(P1).简单图/复合图(P1).相邻(P2).相关 ...

  8. 青岛旅行规划及玩后感

    之前一直属于宅男类型,出去玩也都是周边短途1日游,不需要什么规划,想来去南浔的那次属于最有规划的了,网上订了门票,其他的都是走到哪算到哪. 2012年6月30号的青岛行算是第一次意义上自己的规划旅行, ...

  9. 离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...

    下面的链接是精华版思路,亮点是对第六问的探讨. 高度概括一下:第一问曼哈顿,第二问用免疫,三问增加任务单,四问增加拣货员,五问改变复核台,六问亮点来探讨~ 有点皮 MathorCup C题 仓内拣货优 ...

  10. [CTSC2016]时空旅行(线段树+凸包)

    应该是比较套路的,但是要A掉仍然不容易. 下面理一下思路,思路清楚了也就不难写出来了. 0.显然y,z坐标是搞笑的,忽略即可. 1.如果x不变,那么直接set即可解决. 2.考虑一个空间和询问x0,通 ...

最新文章

  1. 零基础入门学习 Python(4)条件分支、while循环、逻辑连接符、引入外援
  2. 火灾检测、人流量统计… 这个开源项目太香了!
  3. mysql与ms sql server_MS SQL Server和MySQL区别
  4. 分享Kali Linux 2017年第12周镜像文件
  5. mysql 用一条sql语句修改两个表里的内容,一条sql语句update更新两个表
  6. Linux怎么调oracle存储,Linux 环境下Oracle安装与调试(四)之视图、存储过程
  7. 鸿蒙系统对手机性能的提升,鸿蒙OS手机版再爆新特性,流畅度和性能大幅提升,用户评价很高...
  8. 江门计算机职称考试时间,江门职称计算机考试时间
  9. python正弦函数幂级数展开_正余弦函数的幂级数展开
  10. UART、RS-232、RS-422、RS-485
  11. 中国各种茶叶及功效(绿茶\红茶\花茶\乌龙茶\白茶\砖茶)
  12. idea快速切换不同JDK版本
  13. 技术小咖之基于SDK的第一个windows图形界面程序
  14. word或excel打开很慢的处理办法
  15. 《Python安全攻防:渗透测试实战指南》学习一
  16. 【烈日炎炎战后端】JAVA基础(3.4万字)
  17. js把日期字符串转换成时间戳 阿星小栈
  18. 连接数据库SSL警告: Establishing SSL connection without server’s identity verification is not recommended.
  19. 20、Java——迷你图书管理器(对象+集合)
  20. 如何给html文件夹密码,怎样给文件夹加上密码_分享两种给文件夹设密码的方法...

热门文章

  1. python 线程锁_Python3多线程执行任务含线程同步锁
  2. RabbitMQ教程_4 Java 使用rabbitmq
  3. RabbitMQ教程_1 引言
  4. python写入指定路径的文件_python 从shell读取指定文件以及写入指定文件
  5. python为什么会出现无响应怎么办_python定时检测无响应进程并重启的实例代码
  6. 用python开发的运维管理系统下载_GitHub - jiegangwu/OPMS_v3: 基于 Python 3.5 + Django 2.0 开发的运维管理系统...
  7. mapreduce task与spark task对比
  8. java Context类
  9. 【本人秃顶程序员】Java程序员成长三部曲!
  10. 2018 noip 考前临死挣扎