传送门

分块好题。

题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的)。


思路:

考虑分块维护答案。

我们把每个点看成(i,sumi)(i,sum_i)(i,sumi​)答案一定会在凸包上,于是我们每个块维护一个凸包。

然后发现 每次前缀和可以分区域修改,在区域内的相当于给所有点的连线加一个斜率,对于区域外的相当于打一个addaddadd标记,于是给每个块维护整体加标记,斜率增加的首项,斜率的增量标记即可。

查询的时候每个块在凸包上二分一波。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans*w;
}
typedef long long ll;
const ll inf=1e18;
const int N=1e5+5;
int stk[N],top=0,p[505][505],n,m,sig,st[N],ed[N],len[N],blo[N];
ll sum[N],add[N],fi[N],det[N],a[N];
inline ll calc(int x){return !x||x==n+1?-inf:a[x]+add[blo[x]]+fi[blo[x]]+det[blo[x]]*(x-st[blo[x]]);}
inline double slope(int x,int y){return (double)(a[x]-a[y])/(x-y);}
inline void build(int id){
	stk[top=1]=st[id];
	for(ri i=st[id]+1;i<=ed[id];++i){
		while(top>=2&&slope(stk[top],stk[top-1])<slope(stk[top-1],i))--top;
		stk[++top]=i;
	}
	stk[0]=0,stk[top+1]=n+1,len[id]=top;
	for(ri i=0;i<=top+1;++i)p[id][i]=stk[i];
}
inline void pushdown(int id){
	ll tmp=fi[id];
	for(ri i=st[id];i<=ed[id];++i)a[i]+=tmp,tmp+=det[id],a[i]+=add[id];
	fi[id]=det[id]=add[id]=0;
}
inline void update(int l,int r,ll v){
	int L=blo[l],R=blo[r];
	ll tmp=v*(st[L+1]-l+1);
	for(ri i=L+1;i<R;++i)fi[i]+=tmp,det[i]+=v,tmp+=sig*v;
	pushdown(L);
	tmp=v;
	for(ri i=l;i<=min(r,ed[L]);++i)a[i]+=tmp,tmp+=v;
	build(L);
	pushdown(R);
	if(L^R){
		tmp=v*(st[R]-l+1);
		for(ri i=st[R];i<=r;++i)a[i]+=tmp,tmp+=v;
	}
	tmp=v*(r-l+1);
	for(ri i=r+1;i<=ed[R];++i)a[i]+=tmp;
	build(R);
	for(ri i=R+1;i<=blo[n];++i)add[i]+=tmp;
}
inline ll ask(int id){
	int l=1,r=len[id];
	ll t1,t2,t3;
	while(l<=r){
		int mid=l+r>>1;
		t1=calc(p[id][mid-1]),t2=calc(p[id][mid]),t3=calc(p[id][mid+1]);
		if(t1<t2&&t2<t3)l=mid+1;
		else if(t1>t2&&t2>t3)r=mid-1;
		else return t2;
	}
	return -inf;
}
inline ll query(int l,int r){
	int L=blo[l],R=blo[r];
	ll ret=-inf;
	for(ri i=L+1;i<R;++i)ret=max(ret,ask(i));
	for(ri i=l;i<=min(r,ed[L]);++i)ret=max(ret,calc(i));
	if(L^R)for(ri i=st[R];i<=r;++i)ret=max(ret,calc(i));
	return ret;
}
int main(){
	n=read(),sig=sqrt(n);
	for(ri i=1;i<=n;++i)a[i]=read()+a[i-1],blo[i]=(i-1)/sig+1,ed[blo[i]]=i;
	a[0]=a[n+1]=-inf;
	for(ri i=1;i<=blo[n];++i)st[i]=(i-1)*sig+1,build(i);
	for(ri tt=read(),op,l,r;tt;--tt){
		ll v;
		op=read(),l=read(),r=read();
		if(!op)v=read(),update(l,r,v);
		else cout<<query(l,r)<<'\n';
	}
	return 0;
}

2019.01.20 bzoj2388: 旅行规划(分块+凸包)的更多相关文章

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

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

  2. BZOJ 2388: 旅行规划 [分块 凸包 等差数列]

    传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...

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

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

  4. BZOJ2388 : 旅行规划

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

  5. 2019.01.20 bzoj2238: Mst(kruskal+树链剖分)

    传送门 树链剖分菜题. 题意简述:给一个无向图,边有边权,每次询问删一条边(对后面的询问无影响)之后的最小生成树. 思路: 先跑一次kruskalkruskalkruskal并把跑出来的最小生成树给链 ...

  6. 2019.01.20 bzoj3784: 树上的路径(二分答案+点分治)

    传送门 点分治好题. 题意简述:给一棵带边权的树,问所有路径中前mmm大的.m≤300000m\le300000m≤300000 思路: 网上有题解写了可以通过什么点分治序转化成超级钢琴那道题的做法蒟 ...

  7. 2019.01.20 bzoj5158 Alice&Bob(拓扑排序+贪心)

    传送门 短代码简单题. 题意简述:对于一个序列XXX,定义其两个伴随序列a,ba,ba,b,aia_iai​表示以第iii个数结尾的最长上升子序列长度,bib_ibi​表示以第iii个数开头的最长下降 ...

  8. 2019.01.20 NOIP模拟 迅雷(kruskal/二分+并查集)

    传送门 题意简述:给一张带权无向图,有a,ba,ba,b两类特殊点和普通点,问使得至少有一个aaa和一个bbb连通所需要的所有边边权最小值的最大值是多少. 思路: 一眼发现可以二分,考虑怎么check ...

  9. 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)

    传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...

随机推荐

  1. phpStudy安装教程

    1.在phpStudy官网下载安装包(http://phpstudy.php.cn/)2.解压安装后,若提示没有“VC9.VC11.VC14运行库,注意是X86 32位”,则在phpStudy下载对应 ...

  2. 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛----随手记录帖

    这是跟学长学姐组队来打的最爽的一次比赛了,也可能是互相组队最后一次比赛了,南哥和楼学姐,省赛之后就退役了,祝他们能考研和面试都有happy ending! 虽然最后没有把F题的n^2约数的数学题写完, ...

  3. phpword根据模板导出word

    参考网址:http://phpword.readthedocs.io/en/latest/installing.html 在composer.json中添加 { "require" ...

  4. php中bootstrap框架.popover弹出框,鼠标移动到上面自动显示,离开自动消失

    <div rel="name"></div> <script> $(function(){//显示弹出框 $("[rel=name]& ...

  5. PHP-自动加载原理分析

    说起PHP的自动加载,很多同学可能都会想到各种框架的自动加载功能,PHP规范中的PSR0和PSR4原则,Composer的自动加载功能等等,这些都为我们的开发提供了很大的方便. 那么PHP自动加载的前 ...

  6. POJ 1684 Corn Fields(状压dp)

    描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...

  7. TOJ 2778 数据结构练习题――分油问题(广搜和哈希)

    描述 设有大小不等的三个无刻度的油桶,分别能盛满x,y,z公升油.初始时,第一个油桶盛满油,第二.三个油桶为空,在某一个油桶上分出targ公升油. 输入 输入包含多组测试数据.每组数据包含一行.分别x ...

  8. HBase数据库集群配置【转】

    https://www.cnblogs.com/ejiyuan/p/5591613.html HBase简介 HBase是Apache Hadoop中的一个子项目,是一个HBase是一个开源的.分布式 ...

  9. spyder在编辑过程中被自己弄乱了,想要恢复成安装时默认的格式或者重置页面格式的解决办法

    打开spyder,tools-->Reset Spyder to factory defaults,按照如上操作即可恢复成安装时的默认格式.

  10. C语言的那些事

    变量的存数类型: 1:静态变量:凡是在代码任何快之外声明的变量总是存储在静态内存内,也就是不属于堆栈的内存. 对于这类变量.你无法对它们制指定存储类型. 2:存储于堆栈中,称为自动变量.当程序执行到声 ...