JZOJ 6664. 【2020.05.28省选模拟】最优化
\(\text{Solution}\)
原题:\(\text{Honorable Mention}\)
一个费用流做法,\(S\) 向 \(2i-1\) 连流量为 \(1\),费用为 \(0\) 的边,\(2i\) 向 \(T\) 连流量为 \(1\),费用为 \(0\) 的边
\(2i-1\) 向 \(2i\) 连流量为 \(1\),费用为 \(a_i\) 的边。然后增广 \(k\) 次即为答案
既然用了费用流模型那么这个关于 \(k\) 的函数自然是凸函数
于是可以考虑一些优化
比如,多组询问想到将区间拆成 \(O(\log n)\) 段线段树上的区间,处理每个区间上的函数值,合并可以做到 \(O(n)\) 了
也就是要维护凸包,闵科夫斯基和,就可以 \(O(n\log n)\) 预处理凸包了
但这样还是 \(O(nQ)\) 的,仍然是暴力
每个询问有 \(O(\log n)\) 个凸包,合并代价很高
考虑 \(\text{WQS}\) 二分的威力,想想凸包合并时 \(f_{i+j}=f_i+f_j\),又点 \((i,f_i)\) 考虑成 \(f_i=ki+b_i,f_j=kj+b_j\)
那么合并后的凸包 \((i+j,f_{i+j})\) 有 \(f_{i+j}=k(i+j)+b_{i+j}\),也就是启示我们 \(\text{WQS}\) 二分斜率后在每个凸包上找到对应斜率的值直接合并值,然后用 \(WQS\) 二分的方式算出答案
于是就做到 \(O(n\log n+Q\log V \log ^2n)\) 了
注意事项:
- \(\text{WQS}\) 一定要注意斜率变大或者变小会导致分的段数变多还是变少,同时二分写法要和求最值的写法相统一
如本题写了分的段数 \(\ge k\) 时更新答案,那么求最值,值相等时优先取段数多的 - 传参事项,传
vector
时加个&
就不会发生复制导致超时的问题了(因为这题某函数本身并不需要遍历整个vector
,只要也只能 \(O(\log n)\) 做某些特定事情复杂度才对)
\(\text{Code}\)
#include <bits/stdc++.h>
#define IN inline
#define eb emplace_back
#define LL long long
#define Vec vector<LL>
using namespace std;
template<typename Tp>
IN void read(Tp &x) {
x = 0; char ch = getchar(); int f = 0;
for(; !isdigit(ch); f |= (ch == '-'), ch = getchar());
for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
if (f) x = ~x + 1;
}
const int N = 35005;
const LL INF = 2e9;
int n, a[N];
LL pans[2], pcnt[2], tans[2], tcnt[2];
struct SegmentTree {
#define ls (p << 1)
#define rs (ls | 1)
Vec tr[N << 2][2][2];
IN Vec merge(Vec &a, Vec &b) {
if (a.empty() || b.empty()) return{};
Vec ret(a.size() + b.size() - 1, -INF);
int l = 0, r = 0; if (a[0] != -INF && b[0] != -INF) ret[0] = a[0] + b[0];
while (l < a.size() || r < b.size()) {
if (l >= a.size() - 1 && r >= b.size() - 1) break;
if (l == a.size() - 1) ++r; else if (r == b.size() - 1) ++l;
else if (a[l + 1] - a[l] > b[r + 1] - b[r]) ++l; else ++r;
if (a[l] != -INF && b[r] != -INF) ret[l + r] = a[l] + b[r];
}
return ret;
}
IN void shift(Vec tmp, Vec &res) {
for(int i = 1; i < tmp.size(); i++) res[i - 1] = max(res[i - 1], tmp[i]);
}
IN void pushup(int p) {
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++) {
tr[p][i][j] = merge(tr[ls][i][0], tr[rs][0][j]);
shift(merge(tr[ls][i][1], tr[rs][1][j]), tr[p][i][j]);
}
}
void build(int p, int l, int r) {
if (l == r) {
tr[p][0][0] = {0, a[l]}, tr[p][0][1] = tr[p][1][0] = tr[p][1][1] = {-INF, a[l]};
return;
}
int mid = l + r >> 1; build(ls, l, mid), build(rs, mid + 1, r), pushup(p);
}
IN void update(Vec &a, LL k, int x, int y) {
int l = 1, r = a.size() - 1, mid = l + r >> 1, ret = 0;
for(; l <= r; mid = l + r >> 1)
if (a[mid] - a[mid - 1] >= k) ret = mid, l = mid + 1; else r = mid - 1;
if (a[ret] == -INF) return;
for(int i = 0; i < 2; i++) {
LL w = tans[i] + a[ret] - k * ret;
if (!x && pans[y] <= w) pans[y] = w, pcnt[y] = tcnt[i] + ret;
w = tans[i] + a[ret] - k * (ret - i);
if (x && (pans[y] < w || (pans[y] == w && tcnt[i] + ret - i > pcnt[y])))
pans[y] = w, pcnt[y] = tcnt[i] + ret - i;
}
}
IN void Merge(int p, LL k) {
tcnt[0] = pcnt[0], tcnt[1] = pcnt[1], tans[0] = pans[0], tans[1] = pans[1];
pans[1] = -INF, pans[0] = pcnt[0] = pcnt[1] = 0;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++) update(tr[p][i][j], k, i, j);
}
void query(int p, int l, int r, int x, int y, LL k) {
if (x <= l && r <= y) return Merge(p, k), void();
int mid = l + r >> 1;
if (x <= mid) query(ls, l, mid, x, y, k);
if (y > mid) query(rs, mid + 1, r, x, y, k);
}
}seg;
void Query(int L, int R, int k) {
LL res = 0, l = -1e10, r = 1e10, mid = l + r >> 1;
for(; l <= r; mid = l + r >> 1) {
pans[1] = -INF, pans[0] = pcnt[0] = pcnt[1] = 0, seg.query(1, 1, n, L, R, mid);
int z = (pans[0] > pans[1] ? 0 : 1);
if (pcnt[z] >= k) res = pans[z] + mid * k, l = mid + 1; else r = mid - 1;
}
printf("%lld\n", res);
}
int main() {
freopen("maximize.in", "r", stdin);
freopen("maximize.out", "w", stdout);
int q; read(n), read(q);
for(int i = 1; i <= n; i++) read(a[i]);
seg.build(1, 1, n);
for(int i = 1, l, r, k; i <= q; i++) read(l), read(r), read(k), Query(l, r, k);
}
JZOJ 6664. 【2020.05.28省选模拟】最优化的更多相关文章
- 【2020.11.28提高组模拟】T1染色(color)
[2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...
- 3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...
- 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...
- 4.28 省选模拟赛模拟赛 最佳农场 二维卷积 NTT
第一次遇到二维卷积 不太清楚是怎么做的. 40分暴力比对即可. 对于行为或者列为1时 容易想到NTT做快速匹配.然后找答案即可. 考虑这是一个二维的比对过程. 设\(f_{i,j}\)表示以i,j为右 ...
- 【2020.11.28提高组模拟】T2 序列(array)
序列(array) 题目描述 给定一个长为 \(m\) 的序列 \(a\). 有一个长为 \(m\) 的序列 \(b\),需满足 \(0\leq b_i \leq n\),\(\sum_{i=1}^ ...
- http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 项目Beta冲刺(团队)——05.28(6/7)
项目Beta冲刺(团队)--05.28(6/7) 格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺(团队) 团队名称:为了交项目干杯 作业目标:记录Beta敏捷冲刺第6 ...
- 【NOI省选模拟】小奇的花园
「题目背景」 小奇在家中的花园漫步时,总是会思考一些奇怪的问题. 「问题描述」 小奇的花园有n个温室,标号为1到n,温室以及以及温室间的双向道路形成一棵树. 每个温室都种植着一种花,随着季节的变换,温 ...
- JZOJ 5329. 【NOIP2017提高A组模拟8.22】时间机器
5329. [NOIP2017提高A组模拟8.22]时间机器 (File IO): input:machine.in output:machine.out Time Limits: 2000 ms M ...
随机推荐
- 搭建漏洞环境及实战——在Windows系统中安装WAMP
安装成功之后,打开显示 链接:https://pan.baidu.com/s/1NpU7fUYOO_CSM8dNXKdnCw 提取码:mxvw
- 运维、监控、AIOps的几个重要观点
监控是整个运维乃至整个产品生命周期中最重要的一环,通过配置合理的告警机制,采集准确的监控指标,来提前或者尽早发现问题,解决问题,进而保证产品的稳定,提升用户的体验.『分布式实验室』特约记者艾尔斯兰(下 ...
- paozhu c++ web framework 框架原理
paozhu c++ web framework 框架原理 paozhu c++ web framework 使用 asio 网络库,如果用动态库方式还要boost库. paozhu框架 使用两个线程 ...
- 【运维笔录】局域网实现HTTPS访问,只需Nginx + mkcert
1)下载安装mkcert wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1 ...
- HBase详解(02) - HBase-2.0.5安装
HBase详解(02) - HBase-2.0.5安装 HBase安装环境准备 Zookeeper安装 Zookeeper安装参考<Zookeeper详解(02) - zookeeper安装部署 ...
- 为什么 java 容器推荐使用 ExitOnOutOfMemoryError 而非 HeapDumpOnOutOfMemoryError ?
前言 好久没写文章了, 今天之所以突然心血来潮, 是因为昨天出现了这样一个情况: 我们公司的某个手机APP后端的用户(customer)微服务出现内存泄露, 导致OutOfMemoryError, 但 ...
- 前端Linux部署命令与流程记录
以前写过一篇在Linux上从零开始部署前后端分离的Vue+Spring boot项目,但那时候是部署自己的个人项目,磕磕绊绊地把问题解决了,后来在公司有了几次应用到实际生产环境的经验,发现还有很多可以 ...
- SOFAJRaft源码阅读-模块启动过程
本篇文章旨在分析SOFAJRaft中jraft-example模块的启动过程,由于SOFAJRaft在持续开源的过程中,所以无法保证示例代码永远是最新的,要是有较大的变动或者纰漏.错误的地方,欢迎大家 ...
- 使用iframe引入文件后设置响应式宽高以及其他问题解决;
第一 :引入iframe后背景色解决: 需要先设置 被引入文件的body样式 第二:滚动以及其他样式需要设置,span是为了小屏准备的,处理小屏时候元素距离顶部高度问题: 这个是span 的样式 然后 ...
- 【ASP.NET Core】动态映射MVC路由
ASP.NET Core 中的几大功能模块(Razor Pages.MVC.SignalR/Blazor.Mini-API 等等)都以终结点(End Point)的方式公开.在HTTP管道上调用时,其 ...