传送门

首先可以设 \(f[l][r]\) 表示 \([l,r]\) 的答案

设 \(x\) 为区间 \([l,r]\) 的最大值的位置,那么

\(f[l][r] = min(f[l][x-1]+h[x]\times (r-x+1),f[x+1][r]+h[x]\times (x-l+1))\)

这样的 \(dp\) 结构形成了笛卡尔树

那么考虑在笛卡尔树上维护 \(dp\)

对于笛卡尔树上的一个点 \(x\) 它有一个区间 \([l,r]\),考虑维护 \(f[l][i]\) 和 \(f[i][r],i\in [l,r]\)

对于固定左端点的 \(f[l][i]\)(\(f[i][r]\) 类似)

1首先可以由 \(x\) 在笛卡尔树的左儿子继承,即 \(i<x\)

2\(i=x\) 那么 \(f[l][x]=f[l][x-1]+h[x]\)

3\(i>x\) 那么 \(f[l][i]=min(f[l][x-1]+h[x]\times (i-x+1),f[x+1][i]+h[x]\times (x-l+1))\)

前两个好办,对于3,可以证明,这个 \(min\) 的函数是存在一个分界点,使得在左边一个更优,而右边另一个最优,并且具有可二分性

证明

只需要证明下面的东西即可

\(f[l][x-1]+(i-x+1)\times h[x]-(f[x+1][i]+(x-l+1)\times h[x])(\ge)\le\\
f[l][x-1]+((i+1)-x+1)\times h[x]-(f[x+1][i+1]+(x-l+1)\times h[x])\)

因为

\(f[x+1][i+1]-f[x+1][i]\le h[x]\)

那么可以证明上式取 \(\le\)

那么直接二分端点就好了

现在只需要支持区间加,区间对等差数列取 \(min\),单点询问这些操作

可以离线线段树统计答案或者主席树在线回答

# include "meetings.h"
# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn(7.5e5 + 5); struct Segment {
ll covk[maxn << 2], covb[maxn << 2], add[maxn << 2], vl[maxn << 2], vr[maxn << 2];
int cov[maxn << 2]; inline void Cover(int x, int l, int r, ll k, ll b) {
cov[x] = 1, add[x] = 0, vl[x] = k * l + b, vr[x] = k * r + b, covk[x] = k, covb[x] = b;
} inline void Addv(int x, ll v) {
add[x] += v, vl[x] += v, vr[x] += v;
} inline void Pushdown(int x, int l, int mid, int r) {
if (cov[x]) {
Cover(x << 1, l, mid, covk[x], covb[x]);
Cover(x << 1 | 1, mid + 1, r, covk[x], covb[x]);
cov[x] = 0;
}
if (add[x]) Addv(x << 1, add[x]), Addv(x << 1 | 1, add[x]), add[x] = 0;
} ll Query(int x, int l, int r, int p) {
if (l == r) return vl[x];
int mid = (l + r) >> 1;
Pushdown(x, l, mid, r);
ll ret = (p <= mid ? Query(x << 1, l, mid, p) : Query(x << 1 | 1, mid + 1, r, p));
vl[x] = vl[x << 1], vr[x] = vr[x << 1 | 1];
return ret;
} void Chkmin(int x, int l, int r, int ql, int qr, ll k, ll b, ll v) {
if (ql <= l && qr >= r) {
if (k * r + b <= vr[x] + v && k * l + b <= vl[x] + v) {
Cover(x, l, r, k, b);
return;
}
if (k * l + b >= vl[x] + v && k * r + b >= vr[x] + v) {
Addv(x, v);
return;
}
}
int mid = (l + r) >> 1;
Pushdown(x, l, mid, r);
if (ql <= mid) Chkmin(x << 1, l, mid, ql, qr, k, b, v);
if (qr > mid) Chkmin(x << 1 | 1, mid + 1, r, ql, qr, k, b, v);
vl[x] = vl[x << 1], vr[x] = vr[x << 1 | 1];
}
} fix_l, fix_r; int q, n, h[maxn], st[20][maxn], lg[maxn], qryl[maxn], qryr[maxn];
vector <ll> ans;
vector <int> qry[maxn]; inline int Max(int x, int y) {
return h[x] > h[y] ? x : y;
} inline int RMQ(int l, int r) {
int len = lg[r - l + 1];
return Max(st[len][l], st[len][r - (1 << len) + 1]);
} void Solve(int l, int r) {
if (l > r) return;
int mid = RMQ(l, r), i, len = qry[mid].size(), id;
ll fl = 0, fr = 0;
Solve(l, mid - 1), Solve(mid + 1, r);
for (i = 0; i < len; ++i) {
id = qry[mid][i];
ans[id] = (ll)h[mid] * (qryr[id] - qryl[id] + 1);
if (qryl[id] < mid) ans[id] = min(ans[id], (ll)(qryr[id] - mid + 1) * h[mid] + fix_r.Query(1, 1, n, qryl[id]));
if (qryr[id] > mid) ans[id] = min(ans[id], (ll)(mid - qryl[id] + 1) * h[mid] + fix_l.Query(1, 1, n, qryr[id]));
}
if (l < mid) fl = fix_r.Query(1, 1, n, l);
if (r > mid) fr = fix_l.Query(1, 1, n, r);
fix_r.Chkmin(1, 1, n, l, mid, -h[mid], fr + (ll)h[mid] * (mid + 1), (ll)h[mid] * (r - mid + 1));
fix_l.Chkmin(1, 1, n, mid, r, h[mid], fl - (ll)h[mid] * (mid - 1), (ll)h[mid] * (mid - l + 1));
} vector <ll> minimum_costs(vector <int> _h, vector <int> _l, vector <int> _r) {
int i, j, mid;
q = _l.size(), n = _h.size();
for (i = 0; i < n; ++i) st[0][i + 1] = i + 1, h[i + 1] = _h[i];
for (i = 2; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
for (j = 1; j <= lg[n]; ++j)
for (i = 1; i + (1 << j) - 1 <= n; ++i)
st[j][i] = Max(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
ans.resize(q);
for (i = 0; i < q; ++i) {
mid = RMQ(_l[i] + 1, _r[i] + 1);
qry[mid].push_back(i);
qryl[i] = _l[i] + 1, qryr[i] = _r[i] + 1;
}
Solve(1, n);
return ans;
}

UOJ#410. 【IOI2018】会议的更多相关文章

  1. [IOI2018]会议——分治+线段树

    题目链接: [IOI2018]meetings 题目大意:有$n$座山峰,每座山峰有一个高度,有$q$次询问,每次需要确定一个开会山峰使$[l,r]$所有山峰上的人都前往开会山峰,一个山峰的人去开会的 ...

  2. UOJ#407. 【IOI2018】狼人 Kruskal,kruskal重构树,主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ407.html 题解 套路啊. 先按照两个节点顺序各搞一个kruskal重构树,然后问题转化成两棵krus ...

  3. UOJ#405. 【IOI2018】组合动作

    原文链接https://www.cnblogs.com/zhouzhendong/p/IOI2018Day1T1.html 题解 首先二分一下,花费2次操作求出第一位的字符. 假设第一个字符是 Y,答 ...

  4. [IOI2018] meetings 会议

    https://www.luogu.org/problemnew/show/P5044 题解 这种关于最大值或者最小值的问题,可以往笛卡尔树的方面想. 先考虑一个朴素的\(dp\),设\(dp[l][ ...

  5. 洛谷 P5044 - [IOI2018] meetings 会议(笛卡尔树+DP+线段树)

    洛谷题面传送门 一道笛卡尔树的 hot tea. 首先我们考虑一个非常 naive 的区间 DP:\(dp_{l,r}\) 表示区间 \([l,r]\) 的答案,那么我们考虑求出 \([l,r]\) ...

  6. [Z] 计算机类会议期刊根据引用数排名

    一位cornell的教授做的计算机类期刊会议依据Microsoft Research引用数的排名 link:http://www.cs.cornell.edu/andru/csconf.html Th ...

  7. 【UOJ#196】【BZOJ4574】[Zjoi2016]线段树

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4574 http://uoj.ac/problem/196 考虑数字随机并且值域够大,我们 ...

  8. [IOI2018]狼人

    [IOI2018]狼人 luogu UOJ 对人形和狼形分别建克鲁斯卡尔重构树 每次询问就是对于两棵树dfs序的一个二维数点,主席树维护 #include<bits/stdc++.h> u ...

  9. [IOI2018]组合动作

    IOI2018 组合动作 UOJ 首先显然可以两次试出首字母 考虑增量构造 假设首字母为A,且已经试出前i个字母得到的串s 我们考虑press这样一个串s+BB+s+BX+s+BY+s+XA 首先这个 ...

随机推荐

  1. performSelector 的缺点

    在内存管理方面容易有缺失.无法确定将要执行的选择子具体是什么,所以 ARC 无法插入适当的内存管理方法 选择子的返回类型只能是 id,最多有两个参数. 所以尽量避免使用这个东西. 下面来自苹果的文档 ...

  2. iOS 设置textfield的最大文本长度

    //在现实开发中  需要控制文本输入长度 并实时做短信验证,代码如下 [self.textField addTarget:self action:@selector(codeChange:) forC ...

  3. OS之内存管理 ---基本的内存管理策略(二)

    分段 基本方法 分段就是基于用户视图的内存管理方案.逻辑地址空间是由一组段构成的,每个段都有名称和长度.地址指定了段名称和段内偏移.因此用户通过两个量来指定地址:段名称和段偏移. 为了简单,进行对段的 ...

  4. POJ 1157

    #include<iostream> //成大才子---经典代码~ #include<stdio.h> #include<algorithm> #define MA ...

  5. 【PaddlePaddle系列】CIFAR-10图像分类

    前言 本文与前文对手写数字识别分类基本类似的,同样图像作为输入,类别作为输出.这里不同的是,不仅仅是使用简单的卷积神经网络加上全连接层的模型.卷积神经网络大火以来,发展出来许多经典的卷积神经网络模型, ...

  6. 做了三年的菜鸟web前端的感悟

    作为一名真正的菜鸟我想没有比我更加实在的了,三年之中,虽然做了一二三四五六七个项目,基本都是jQuery写的,但是还是一名不折不扣的菜鸟.这让我很尴尬啊,面对前端大量要学习的东西,真的是很头疼,技术更 ...

  7. 理解HashMap的原理

    HashMap内部数据结构        HashMap内部采用数组和链表结合的方式来存取数据(见下图).这种方式有什么好处呢? 我们知道,数组操作对于检索是O(1)的,能够很快的根据数组的下标定位对 ...

  8. .NET源码Stack<T>和Queue<T>的实现

    这阵子在重温数据结构的时候,顺便用ILSpy看了一些.NET类库的实现,发现一些基本的数据结构的实现方法也是挺有意思的,所以这里拿出来跟大家分享一下.这篇文章讨论的是Stack和Queue的泛型实现. ...

  9. linux内核模块的安全

    linux可以动态的加载内核模块,在很多场合可能需要确保加载内核的安全性.如果被攻击者加载恶意内核模块,将会使得内核变得极其危险. 当然,稳妥的做法就是给内核模块进行签名,内核只加载能正确验证的签名. ...

  10. Css权重解析

    Css权重解析 关于CSS权重,我们需要一套计算公式来去计算,这个就是 CSS Specificity,我们称为CSS 特性或称非凡性,它是一个衡量CSS值优先级的一个标准 具体规范入如下: spec ...