「BZOJ2388」旅行规划
分块+凸包
求出前缀和数组s
对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列。r~n加上k*(r-l+1)。
分块之后对每一块维护两个标记,一个记录它加的等差数列(两个等差数列相加仍是等差数列),一个记录它整体加的值。
设首项的标记为A,公差为B
查询一块的最大值,就是询问最大的 s[i] + i*B
可以看成询问平面上的若干横坐标为i,纵坐标为si,斜率为B的直线的最大纵截距,那么维护一个上凸壳即可。
对于散点修改后暴力重构凸包。
对于询问在凸包上三分。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=2e5+;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,bl[N],sz,tot,top[];
LL s[N],lz[],A[],B[]; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct pt {
LL x,y;
pt(){}
pt(LL x,LL y):x(x),y(y){}
friend bool operator <(const pt&A,const pt&B) {
return A.x<B.x||(A.x==B.x&&A.y<B.y);
}
}p[N],q[][],D; pt operator - (const pt&A,const pt&B) { return pt(A.x-B.x,A.y-B.y); } LL cross(pt A,pt B) { return A.x*B.y-A.y*B.x; }
LL dot(pt A,pt B) { return A.x*B.x+A.y*B.y; }
LL length(pt A) { return dot(A,A); } void make_ham(int id,int l,int r) {
For(i,l,r) p[i]=pt(i,s[i]);
int tp=;
q[id][++tp]=p[l];
For(i,l+,r) {
while(tp>&&cross(q[id][tp]-q[id][tp-],p[i]-q[id][tp-])>=) tp--;
q[id][++tp]=p[i];
}
top[id]=tp;
} void get_pre() {
sz=sqrt(n); tot=n/sz; if(n%sz) tot++;
For(i,,n) {
bl[i]=(i-)/sz+;
p[i]=pt(i,s[i]);
}
For(i,,tot) {
int dn=(i-)*sz+,up=min(n,i*sz);
make_ham(i,dn,up);
}
} void down(int x) {
int l=(x-)*sz+,r=min(n,x*sz);
if(lz[x]) {
For(i,l,r) s[i]+=lz[x];
lz[x]=;
}
if(A[x]||B[x]) {
For(i,l,r) s[i]+=A[x]+B[x]*(i-l);
A[x]=B[x]=;
}
} void change(int l,int r,LL k) {
down(bl[l]);
down(bl[r]);
if(bl[l]==bl[r]) {
For(i,l,r) s[i]+=k*(i-l+);
For(i,r+,bl[l]*sz) s[i]+=k*(r-l+);
make_ham(bl[l],(bl[l]-)*sz+,min(bl[l]*sz,n));
For(i,bl[l]+,tot) lz[i]+=k*(r-l+);
return;
}
For(i,l,min(n,bl[l]*sz)) s[i]+=k*(i-l+);
make_ham(bl[l],(bl[l]-)*sz+,min(bl[l]*sz,n));
For(i,bl[l]+,bl[r]-) {
A[i]+=k*((i-)*sz+-l+); B[i]+=k;
}
For(i,(bl[r]-)*sz+,min(n,bl[r]*sz)) {
if(i<=r) s[i]+=k*(i-l+);
else s[i]+=k*(r-l+);
}
For(i,bl[r]+,tot) lz[i]+=k*(r-l+);
make_ham(bl[r],(bl[r]-)*sz+,min(bl[r]*sz,n));
} LL calc(int x) { return s[x]+lz[bl[x]]+A[bl[x]]+B[bl[x]]*(x-(bl[x]-)*sz-); } LL get_ans(int x) {
int l=,r=top[x];
while(l<=r) {
if(l+>=r) return max(calc(q[x][l].x),calc(q[x][r].x));
int mid=((l+r)>>);
LL a=calc(q[x][mid-].x),b=calc(q[x][mid].x),c=calc(q[x][mid+].x);
if(a<b&&b<c) l=mid+;
else if(a>b&&b>c) r=mid-;
else return b;
}
return ;
} LL qry(int l,int r) {
LL rs=-1e18;
if(bl[l]==bl[r]) {
For(i,l,r) rs=max(rs,calc(i));
return rs;
}
For(i,l,min(n,bl[l]*sz)) rs=max(rs,calc(i));
For(i,bl[l]+,bl[r]-)
rs=max(rs,get_ans(i));
For(i,(bl[r]-)*sz+,r) rs=max(rs,calc(i));
return rs;
} #define DEBUG
int main() {
#ifdef DEBUG
freopen("2388.in","r",stdin);
freopen("2388.out","w",stdout);
#endif
read(n);
For(i,,n) read(s[i]),s[i]+=s[i-];
get_pre();
read(m);
while(m--) {
int o,l,r; LL v;
read(o); read(l); read(r);
if(!o) {
read(v);
change(l,r,v);
}
else printf("%lld\n",qry(l,r));
}
return ;
}
/*
20
32 -5 -28 -1 -39 30 44 38 -44 -6 -8 33 -45 -4 39 -32 -28 -6 42 -24
20
0 7 19 48
0 7 13 5
1 13 17
*/
「BZOJ2388」旅行规划的更多相关文章
- 「JSOI2013」旅行时的困惑
「JSOI2013」旅行时的困惑 传送门 由于我们的图不仅是一个 \(\text{DAG}\) 而且在形态上还是一棵树,也就是说我们为了实现节点之间互相可达,就必须把每条边都覆盖一次,因为两个点之间的 ...
- 「JSOI2010」旅行
「JSOI2010」旅行 传送门 比较妙的一道 \(\text{DP}\) 题,思维瓶颈应该就是如何确定状态. 首先将边按边权排序. 如果我们用 \(01\) 串来表示 \(m\) 条边是否在路径上, ...
- 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- Loj #3057. 「HNOI2019」校园旅行
Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...
- LibreOJ 2003. 「SDOI2017」新生舞会 基础01分数规划 最大权匹配
#2003. 「SDOI2017」新生舞会 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 【LibreOJ】#6395. 「THUPC2018」城市地铁规划 / City 背包DP+Prufer序
[题目]#6395. 「THUPC2018」城市地铁规划 / City [题意]给定n个点要求构造一棵树,每个点的价值是一个关于点度的k次多项式,系数均为给定的\(a_0,...a_k\),求最大价值 ...
- 「2014-2-6」TokuMX and MongoDB related materials collection
简介参考 TokuMX 和 MongoDB 各自的官方站点. ## Tokutek 最重要的特点和 marketing word 是所谓 fractal tree indexing te ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- 「APIO2017」商旅
「APIO2017」商旅 题目描述 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个商人.科巴有 \(N\) 个集市, ...
随机推荐
- 利用IK分词器,自定义分词规则
IK分词源码下载地址:https://code.google.com/p/ik-analyzer/downloads/list lucene源码下载地址:http://www.eu.apache.or ...
- mybatis 处理CLOB/BLOB类型数据
BLOB和CLOB都是大字段类型. BLOB是按二进制来存储的,而CLOB是可以直接存储文字的. 通常像图片.文件.音乐等信息就用BLOB字段来存储,先将文件转为二进制再存储进去.文章或者是较长的文字 ...
- 2018-10-8-Win10-使用-GHO-安装出现-UWP-软件打开闪退-应用商店无法安装软件
title author date CreateTime categories Win10 使用 GHO 安装出现 UWP 软件打开闪退 应用商店无法安装软件 lindexi 2018-10-8 18 ...
- arm-linux-strip 的使用
3.2.1 1. 移除所有的符号信息 [arm@localhost gcc]#cp hello hello1 [arm@localhost gcc]#armlinuxstrip strip ...
- JS事件 失焦事件(onblur)onblur事件与onfocus是相对事件,当光标离开当前获得聚焦对象的时候,触发onblur事件,同时执行被调用的程序。
失焦事件(onblur) onblur事件与onfocus是相对事件,当光标离开当前获得聚焦对象的时候,触发onblur事件,同时执行被调用的程序. 如下代码, 网页中有用户和密码两个文本框.当前光标 ...
- C++之constexpr
一.常量表达式:是指值不会改变并且在编译过程就能得到计算结果的表达式.一个对象是不是常量表达式是由它的数据类型和初始值共同决定. ;//虽然初始值是字面值常量,但是它的数据类型只是普通int. con ...
- PHP算法之整数转罗马数字
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1.12 ...
- 三角形的实现和盒模型、层模型、浮动模型、定位、权重、margin问题
相邻的border会平分所占的区域,出现一个斜线, .my_triangle{ width: 10px; height: 10px; background-color: blue; border-wi ...
- [JZOJ6344] 【NOIP2019模拟2019.9.7】Huge Counting
题目 题目大意自己看题去-- 正解 比赛时在刚第二题,所以根本没有时间思考-- 模型可以转化为从\((x_1,x_2,..,x_n)\)出发到\((1,1)\)的方案数模\(2\). 方案数就用有重复 ...
- SpringMVC的孪生兄弟WebFlux
一.入门文字介绍 官方口水话简短翻译: Spring WebFlux是一个非阻塞的Web框架,用于利用多核,短时间可一处理大量并发连接. 非阻塞式 在servlet3.1提供了非阻塞的API,WebF ...