bzoj2388(分块 凸包)
好像没有什么高级数据结构能够很高效地实现这个东西;
那就上万能的分块,我们用一些数形结合的思想,把下标看成横坐标,前缀和的值看成纵坐标;
给区间内每个数都加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(分块 凸包)的更多相关文章
- 2019.01.20 bzoj2388: 旅行规划(分块+凸包)
传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi)答案一定会在凸包上 ...
- BZOJ2388:旅行规划(travel)——分块凸包
题目 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路 ...
- BZOJ2388: 旅行规划(分块 凸包)
题意 题目链接 Sol 直接挂队爷的题解了 分块题好难调啊qwq #include<bits/stdc++.h> #define LL long long using namespace ...
- BZOJ 2388: 旅行规划 [分块 凸包 等差数列]
传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...
- 「BZOJ2388」旅行规划
传送门 分块+凸包 求出前缀和数组s 对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列.r~n加上k*(r-l+1). 分块之后对每一块维护两个标记,一个记录它加的等差数 ...
- 旅行规划(travel)
题目描述 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 nnn 个最著名的经典连接起来,让游客可以通过火车从 ...
- ZROI 19.07.28 序列数据结构/jk
写在前面 dls:"我不会数据结构,但是APIO的数据结构场我写了,还是蛮简单的." T1 CF643G Sol: 有一个\(O(n\log^2n)\)的做法:假设将区间排好序,取 ...
- 【bzoj5089】最大连续子段和 分块+单调栈维护凸包
题目描述 给出一个长度为 n 的序列,要求支持如下两种操作: A l r x :将 [l,r] 区间内的所有数加上 x : Q l r : 询问 [l,r] 区间的最大连续子段和. 其中,一 ...
- CF573E Bear and Bowling 贪心、分块、凸包
传送门 题解搬运工++ 先证明一个贪心做法的正确性:做以下操作若干次,每一次考虑选择没有被选到答案序列中的数加入到答案序列中对答案的贡献,设第\(i\)个位置的贡献为\(V_i\),如果最大的贡献小于 ...
随机推荐
- spirng中的asm与jdk不兼容<已解决>
转载自:spirng中的asm与jdk不兼容<已解决> 前言 不知道前面对eclipse做了什么,使用maven来创建项目,然后转成web,启动的时候一直报错.我弄了好久,还是无法解决,先 ...
- C语言中简单的for循环和浮点型变量
浮点型变量:常数中带有小数点的叫做浮点型 以下用for循环写一个摄氏度和华氏度的转换的C程序 [见 http://www.linuxidc.com/Linux/2013-08/88513.htm ] ...
- vue 环境搭建
目前我们的项目前端都采用的是vue js为了方便开发过程中前后端同事进行功能对接,建议每个同事都准备好前后端环境(前端的同事参考文档第二部分,后端同事请参考第一部分),只要保持前后端代码是最新的就可以 ...
- Python 字符串(count)
字符串 count:(python中的count()函数,从字面上可以知道,他具有统计功能) Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位 ...
- PAT 甲级1001 A+B Format (20)(C++ -思路)
1001 A+B Format (20)(20 分) Calculate a + b and output the sum in standard format -- that is, the dig ...
- Linux CentOS 7 & JDK 1.7 安装与配置
前言 简单记录一下在CentOS 7中安装配置JDK 1.7的全过程~ 下载 首先是jdk 1.7 64bit & 32bit的下载地址: jdk-7u79-linux-x64.tar.gz ...
- “Interrupted by header callback: Server reports Content-Length”如何解决
mock初始化时的错误信息如下: Downloading Packages: [SKIPPED] systemd--.fc25.x86_64.rpm: Already downloaded [SKIP ...
- The valid characters are defined in RFC 7230 and RFC 3986问题
这个问题困扰了我接近两天了!尼玛!网上搜了很多资料,有的给出了解决方案,然后下面的评论说按照楼主做的,没有成功,我一做也确实没有成功.设置了断点,一步一步跟进去看,还是没有头绪.不过有一点可以确认的是 ...
- [JAVA]多线程下如何确定执行顺序性
最近在讨论一个下载任务:要求文件下载后进行打包,再提供给用户下载: 如何确保打包的线程在所有下载文件的线程执行完成后进行呢? 看看下面三个兄弟的本事: CountDownLatch.CyclicBar ...
- Partition Array Into Three Parts With Equal Sum LT1013
Given an array A of integers, return true if and only if we can partition the array into three non-e ...