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\),如果最大的贡献小于 ...
随机推荐
- 在threejs中添加两个场景和相机是需要注意render的参数设置
问题:我刚开始设置了两个场景和相机 但是第二个一直将第一个场景给覆盖了一直找不到原因 解决: 问题出在 renderer.autoClear = false;上 设置render的参数如下: rend ...
- Linux pip安装使用详解
简介 pip是Python有它自己的包管理工具,与yum和apt-get相似. 安装步骤: 1.下载get-pip.py:https://bootstrap.pypa.io/get-pip.py 2. ...
- Java 7.21 游戏:豆机(C++&Java)
PS: 难点在于,随机之后的分隔,理解就很容易了 注意:槽的奇偶情况 C++: #include<iostream> #include<ctime> #include<s ...
- UVA 11235 (RMQ) 频繁出现的数值
题目大意是给出一个非降序排列的数组,然后n个询问,每次询问一个区间内出现次数最多的数的次数. 首先要弄清楚题目的是一个非降序的数组,那么说明相等的数都会在一起,类似于11223334569这样的,那么 ...
- VFIO简介 (转载)
VFIO简介 LTCChina | Nov 20 2013 | Comment (1) | Visits (15204) 概述 VFIO是一套用户态驱动框架,它提供两种基本服务: 向用户态提供访问硬件 ...
- 需求文件requirements.txt的创建及使用
pip freeze >requirements.txt pip install -r requirements.txt
- C++点和箭头操作符用法区别
变量是对象的时候用“.”访问 变量是对象指针的时候用“->”访问 例: #inlclude <iostream> using namespace std; class A { pub ...
- @1-2初识Python爬虫
初识Python爬虫 Python爬虫(入门+进阶) DC学院 环境搭建: Python2与Python3的差异:python2与python3整体差异不大,大多是一些语法上的区别,考虑到py ...
- keepalived配虚拟ip(vip)的作用
keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议. 虚拟路由冗余协议,可以认为是实现路由器高可用的 ...
- python3版本main.py执行产生中间__pycache__详解
__pycache__ 用python编写好一个工程,在第一次运行后,总会发现工程根目录下生成了一个__pycache__文件夹,里面是和py文件同名的各种 *.pyc 或者 *.pyo 文件. 先大 ...