BZOJ2388: 旅行规划(分块 凸包)
题意
Sol
直接挂队爷的题解了
分块题好难调啊qwq


#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e6 + 10;
const LL INF = 6e18;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, block, bel[MAXN], bl[MAXN], br[MAXN], mx;
vector<int> con[MAXN];
LL bg[MAXN], d[MAXN], a[MAXN];
double slope(int x, int y) {
return double (a[y] - a[x]) / (y - x);
}
void rebuild(int id) {
vector<int> &v = con[id]; v.clear();
for(int i = bl[id]; i <= br[id]; i++) {
while(v.size() > 1 && (slope(v[v.size() - 2], i) >= (slope(v[v.size() - 2], v[v.size() - 1])))) v.pop_back();
v.push_back(i);
}
}
LL Find(vector<int> &v, double k, int lef) {
int l = 0, r = v.size() - 1, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if(mid == 0 || (slope(v[mid - 1], v[mid]) > k)) ans = mid, l = mid + 1;
else r = mid - 1;
}
return a[v[ans]] + 1ll * (v[ans] - lef + 1) * (-k);
}
void Modify(int l, int r, int val) {
for(int i = l; i <= min(r, br[bel[l]]); i++) a[i] += 1ll * val * (i - l + 1);
rebuild(bel[l]);
if(bel[l] != bel[r]) {
for(int i = bl[bel[r]]; i <= r; i++) a[i] += 1ll * val * (i - l + 1);
}
for(int i = r + 1; i <= br[bel[r]]; i++) a[i] += 1ll * val * (r - l + 1);
rebuild(bel[r]);
for(int i = bel[l] + 1; i <= bel[r] - 1; i++) {
bg[i] += 1ll * (bl[i] - l + 1) * val - val;
d[i] += val;
}
for(int i = bel[r] + 1; i <= mx; i++) bg[i] += 1ll * val * (r - l + 1);
}
LL Query(int l, int r) {
LL ans = -INF;
for(int i = l; i <= min(r, br[bel[l]]); i++)
chmax(ans, bg[bel[l]] + 1ll * (i - bl[bel[l]] + 1) * d[bel[l]] + a[i]);
if(bel[l] != bel[r]) {
for(int i = bl[bel[r]]; i <= r; i++)
chmax(ans, bg[bel[r]] + 1ll * (i - bl[bel[r]] + 1) * d[bel[r]] + a[i]);
}
for(int i = bel[l] + 1; i <= bel[r] - 1; i++) {
chmax(ans, bg[i] + Find(con[i], -d[i], bl[i]));
}
return ans;
}
signed main() {
N = read(); block = sqrt(N);
for(int i = 1; i <= N; i++) a[i] = read() + a[i - 1], bel[i] = (i - 1) / block + 1, chmax(mx, bel[i]);
// for(int i = 1; i <= 16; i++) cout << a[i] << " ";
for(int i = 1; i <= mx; i++) bl[i] = (i - 1) * block + 1, br[i] = bl[i] + block - 1, rebuild(i);
M = read();
for(int i = 1; i <= M; i++) {
int opt = read();
if(opt == 0) {
int l = read(), r = read(), v = read();
Modify(l, r, v);
} else {
int l = read(), r = read();
cout << Query(l, r) << '\n';
}
}
return 0;
}
/*
16
51 -6867 25916 -19111 -23413 -282 7274 6888 15114 6563 18264 -11811 27336 14638 19495 -10931
1
1 9 16
*/
BZOJ2388: 旅行规划(分块 凸包)的更多相关文章
- BZOJ 2388: 旅行规划 [分块 凸包 等差数列]
传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...
- BZOJ2388:旅行规划(travel)——分块凸包
题目 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路 ...
- 2019.01.20 bzoj2388: 旅行规划(分块+凸包)
传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi)答案一定会在凸包上 ...
- BZOJ2388 : 旅行规划
考虑分块,每块维护两个标记$ts,td$. 那么对于块中一个位置$i$,它的实际值为$i\times td+ts+v_i$. 修改的时候,对于整块,直接打标记,对于零散的暴力修改,然后重构凸壳,时间复 ...
- 「BZOJ2388」旅行规划
传送门 分块+凸包 求出前缀和数组s 对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列.r~n加上k*(r-l+1). 分块之后对每一块维护两个标记,一个记录它加的等差数 ...
- BZOJ 2388--旅行规划(分块&单调栈&二分)
2388: 旅行规划 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 405 Solved: 118[Submit][Status][Discuss] ...
- 旅行规划(travel)
题目描述 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 nnn 个最著名的经典连接起来,让游客可以通过火车从 ...
- bzoj2388(分块 凸包)
好像没有什么高级数据结构能够很高效地实现这个东西: 那就上万能的分块,我们用一些数形结合的思想,把下标看成横坐标,前缀和的值看成纵坐标: 给区间内每个数都加k相当于相邻两点的斜率都加上k: 这种东西我 ...
- @bzoj - 2388@ 旅行规划
目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...
随机推荐
- java极光推送记录
1. 添加poom依赖: <dependency> <groupId>cn.jpush.api</groupId> <artifactId>jigu ...
- C#导出Excel文件Firefox中文件名乱码
首先说明下:我的解决方法不一定适用于其他遇到该问题的人,因为情况多种多样,适合我的方法不一定适合别人,就像我在遇到问题时查到别人的解决方案放到我的代码里却不管用,所以这个方法仅供参考 这两天做了一个导 ...
- Python多线程-Event(事件对象)
Event 事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为False.wait()方法阻塞,直到标志为True.该标志初始为False. 方法: i ...
- sparkshell运行sql报错: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
下载msyql的连接driver https://download.csdn.net/download/xz360717118/10662304 把其中一个: mysql-connector-java ...
- Linux 部署 ASP.NET Core 的一些问题记录
异常错误: 关闭 IP6 #修改 vi /etc/sysctl.conf # 添加如下三条设置 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.co ...
- 二:理解ASP.NET的运行机制(例:基于HttpHandler的URL重写)
url重写就是把一些类似article.aspx?id=28的路径重写成 article/28/这样的路径 当用户访问article/28/的时候我们通过asp.net把这个请求重定向到article ...
- WPF实现在电脑重启或关机时执行某些逻辑
Application类的SessionEnding事件,就是电脑关机或重启时响应的(会话结束事件), 所以只需要在App.xaml中添加SessionEnding <Application x ...
- 数据序列化导读(3)[JSON v.s. YAML]
前面两节介绍了JSON和YAML,本文则对下面的文章做一个中英文对照翻译. Comparison between JSON and YAML for data serialization用于数据序列化 ...
- C++关于sort和priority_queue的运算符重载
C++中的sort函数默认是将元素升序排列的,而priority_queue默认是将元素降序排列的(默认实现的是大顶堆). 自定义运算符用的比较多,以下2种对sort和priority_queue运算 ...
- Android so文件进阶 <一>
0x00 前言 最近一段时间在弄android方面的东西,今天有人发了张截图,问:在要dump多大的内存? 一时之间我竟然想不起来ELF文件的哪个字段表示的是文件大小,虽然最后给出了解决方法,I ...