首页 > 其他分享 >洛谷 P9579「Cfz Round 1」Elevator 另类题解

洛谷 P9579「Cfz Round 1」Elevator 另类题解

时间:2024-01-19 19:13:53浏览次数:29  
标签:mn 洛谷 min int 题解 P9579 leq 跑法 displaystyle

一个赛时想到的另类 DP 做法。

Solution

容易将原题转化为一个人乘电梯每次上下一层。

对于 \(a_i<b_i\) 是好处理的,记 \(\displaystyle m=\max_{1\leq i\leq n}\{a_i,b_i\}\),只需要跑到 \(m\) 即可解决所有这种条件。

对于 \(a_i>b_i\) 的条件,我们除了到 \(m\) 外,还需要额外地从上往下跑。显然我们跑一轮可以解决掉多个询问,设解决的询问集合是 \(S\),则分两类:

  1. 先下后上,代价为 \(\displaystyle(\max_{i\in S}\{a_i\}-\min_{i\in S}\{b_i\})\times 2\),可以跑若干轮。
  2. 到 \(m\) 再下去,代价为 \(m-\min_{i\in S}\{b_i\}\),只能跑一轮。

第二种跑法只能最后跑,故在计算答案时考虑,下文考虑第一种跑法。

将 \(a_i>b_i\) 的询问按 \(a_i\) 排序,设 \(f_{i}\) 是用第一种跑法满足前 \(i\) 个条件的最小额外次数。观察发现,每次处理的条件是一个区间。

证明(可以跳过不看):假设原来两个区间里元素组成的集合分别是是 \(P,Q\),\(\forall i\in P,j\in Q\),\(a_i\leq a_j\)。则考虑将 \(Q\) 中的一个元素放入 \(P\) 中使答案变优。由于放入后,\(P\) 的代价会变大,要是答案变优,需要 \(Q\) 代价变小。若取 \(Q\) 中 \(b_i\) 最小的元素 \(k\) 加入 \(p\),则 \(Q\) 中 \(a_i\) 小于 \(a_k\) 的元素加入 \(P\) 代价不变;若取 \(Q\) 中 \(a_i\) 最大的元素加入 \(P\) 中,由于 \(\forall i\in P,j\in Q\),\(a_i\leq a_j\),代价和变大。证明 \(P\) 中元素加入 \(Q\) 中不优同理。

易得转移方程:

\[f_{i}=\min_{0\leq j<i}\{f_{j}+(a_i-\min_{j<k\leq i}\{b_k\})\times 2\}=\min_{0\leq j<i}\{f_{j}-2\times\min_{j<k\leq i}\{b_k\}\}+2\times a_i \]

考虑优化这个 DP。

令 \(\displaystyle d_x=\min_{x<j\leq i}\{b_j\}\),则转移方程为 \(\displaystyle f_i=\min_{1< j\leq i}\{f_{j-1}-2\times d_j\}+2\times a_i\)。每次更新 \(d_x\gets\min\{d_x,b_i\}\)。
容易发现 \(d\) 是不降序列。用珂朵莉树维护段连续相同的 \(d\)。加入 \(a_i\) 只需要二分出第一个 \(a_i\leq d_j\) 的位置 \(j\),然后将 \(j\sim i\) 合并为新段即可。

为了求出 \(f_i\),还需要维护每块里面的 \(\displaystyle\min_{j-1\leq k\leq i-1}\{f_{k}\}+2\times d\) 和它的前缀 \(\min\)。为了维护它们,合并时还需要用一颗线段树来求出 \(\displaystyle\min_{j-1\leq k\leq i-1}\{f_{k}\}\)。

最后,只需要枚举第二种跑法从哪里开始就行啦,答案为 \(\displaystyle\min_{0\leq i\leq n}\{f_{i}+2m-\min_{i<j\leq n}\{b_i\}\}\)。

时间复杂度 \(\mathcal{O}(n\log n)\)。

Code

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
using namespace std;
namespace Milkcat {
	typedef long long LL;
	typedef pair<LL, LL> pii;
    typedef vector<LL> poly;
	const int N = 1e6 + 5;
	namespace SGT {
	    LL sum[N << 2];
	    inline void push_up(int p) { sum[p] = min(sum[p << 1], sum[p << 1 | 1]); }
	    void modify(int p, int l, int r, int t, LL k) {
	        if (l == r) { sum[p] = k; return; }
	        int mid = (l + r) >> 1;
	        if (t <= mid) modify(p << 1, l, mid, t, k);
	        if (t > mid) modify(p << 1 | 1, mid + 1, r, t, k);
	        push_up(p);
	    }
	    LL query(int p, int l, int r, int nl, int nr) {
	        if (nl <= l && r <= nr) return sum[p];
	        LL mid = (l + r) >> 1;
	        if (nl <= mid && nr > mid)
	            return min(query(p << 1, l, mid, nl, nr), query(p << 1 | 1, mid + 1, r, nl, nr));
	        if (nl <= mid) return query(p << 1, l, mid, nl, nr);
	        if (nr > mid) return query(p << 1 | 1, mid + 1, r, nl, nr);
	    }
	};
	using namespace SGT;
	struct node {
		mutable LL v, l, r, pre;
		node(LL HCY, LL AK, LL IOI, LL Orz) : v(HCY), l(AK), r(IOI), pre(Orz) {}
		bool operator < (const node& x) const { return v < x.v; }
	};
	LL n, m, cnt, x, y, mn, ans, f[N]; pii a[N]; 
	set<node> s;
	int main() {
		memset(sum, 0x3f, sizeof sum);
		memset(f, 0x3f, sizeof f);
		cin >> n;
		for (int i = 1; i <= n; i ++) {
			cin >> x >> y, m = max({m, x, y});
			if (x > y) a[++ cnt] = pii(x, y);
		}
		n = cnt, sort(a + 1, a + 1 + n);
		f[0] = 0, modify(1, 0, n, 0, 0);
		for (int i = 1; i <= n; i ++) {
			auto it = s.lower_bound(node(a[i].se, 0, 0, 0));
			LL t = (it == s.end() ? i : it->l), last = (it == s.begin() ? m + 1 : prev(it)->pre);
			s.erase(it, s.end());
            s.insert(node(a[i].se, t, i, min(last, query(1, 0, n, t - 1, i - 1) - a[i].se * 2)));
			f[i] = prev(s.end())->pre + a[i].fi * 2, modify(1, 0, n, i, f[i]);
		}
		mn = m, ans = INT_MAX;
		for (int i = n; i >= 0; i --)
			ans = min(ans, f[i] + m * 2 - mn), mn = min(mn, a[i].se);
		cout << ans << '\n';
		return 0;
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
    int T = 1;
    while (T --) Milkcat::main();
    return 0;
}

标签:mn,洛谷,min,int,题解,P9579,leq,跑法,displaystyle
From: https://www.cnblogs.com/Milkcatqwq/p/17975396

相关文章

  • 洛谷 P9575 「TAOI-2」喵了个喵 Ⅳ 题解
    Solution先求出所有数的最大公约数\(d\),然后将每个数约去\(d\)。将约去后的数均分,约去前的数也均分。下文讨论的数都是约去\(d\)后的数(包括取的\(x\))。\(n\)为偶数,取\(x=1\),对半分即可。\(n\)不为偶数,且有奇数个偶数。取\(x=2\),设奇数和偶数分别有\(x,y\)个,B组取......
  • 洛谷 P9915 「RiOI-03」3-2 题解
    Preface为啥有蓝啊,这题在机房里15min左右就切了,反倒是2A做了1h。。Solution将矩阵逆时针旋转\(90^{\circ}\),你会发现这是一棵线段树,是父亲左儿子的节点颜色是\(0\),是右儿子的节点颜色是\(1\)。容易发现,联通块一定是一条链。具体地,你从给定的点向上跳,跳到第一个与自己......
  • CF1895E Infinite Card Game 题解
    Solution根据贪心策略,可以发现出完一张牌后对手的出牌是固定的。同理可以算出Monocarp出完一张牌\(a\)后下一次出的牌\(to_a\)。\(a\)和\(to_a\)胜负状态相同。可以发现对所有\(a\)建\(a\toto_a\)后形成的图是内向基环树,一遍dfs即可求出答案。时间复杂度\(\m......
  • /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found问题解决
    有一个go实现的项目代码最近有更新,自己在开发环境上手动构建并运行都没有问题(构建和运行时相同环境,肯定没有问题^_^)。后面通过jenkins构建镜像也没有问题,运行时却报错 之前的版本在jenkins上构建也是成功的,后沟通得知jenkins集群版本最近有更新 那么,大概知道原因了,由于jenk......
  • 洛谷题单指南-模拟和高精度-P1098 [NOIP2007 提高组] 字符串的展开
    原题链接:https://www.luogu.com.cn/problem/P1098题意解读:题目本身是一道模拟题,但是细节点较多,要拿100分,有以下注意点:1、-号两个需要同时为小写字母或者数字,才进行填充2、-号左边>=右边,直接输出-3、对待填充的内容的处理,可以先看是否填充*;小写字母和数字的填充都是前一位asci......
  • CF1214E题解
    PetyaandConstructionSet题目传送门题解一个构造题,结论挺容易猜的。观察到关键信息:\(d_i\len\)。所以我们先把所有奇数编号的点按对应的\(d\)从大到小组成一条链,然后依次考虑偶数号点应该接在链上的哪个点后,容易知道这个点为链上的第\(i+d-1\)个。特殊的,如果接在了最后......
  • CF150C题解
    SmartCheater题目传送门题解首先显然的,每个乘客是独立计算的,然后我们发现,一个乘客在\(i\)到\(i+1\)不买票的期望贡献是一定的,为\(\dfrac{x_{i+1}-x_i}{2}-c*p_i\),所以我们其实就是要对于每个乘客的区间求最大子段和,简单线段树板子,感觉也没啥细节。代码:#include<bits/st......
  • CF1286C1题解
    Madhouse(Easyversion)题目传送门题解这种水题还能有蓝?不能因为困难版是黑就把简单版难度往上强拉啊!第一次问\([1,n]\),第二次问\([1,n-1]\),把读入的所有字符串先各自内部把字符排序(反正本来就是乱序)后存入map,第一次询问有,第二次询问没有的字符串就是原串后缀的乱序,都找出......
  • NOIP2023题解
    目录NOIP2023T1词典(dict)T2三值逻辑(tribool)T3双序列拓展(expand)T4天天爱打卡(run)NOIP2023T1词典(dict)考察:贪心题解Link题目传送门首先任意多次操作本质就是随意排序,所以如果要使\(w_i\)最小,我们一定会使\(w_i\)从\(a\)到\(z\)排,其它都\(z\)到\(a\)排......
  • CF1899G题解
    UnusualEntertainment题目传送门题解真的不要太典,,,考虑点\(u\)是\(v\)的后代等价于\(u\)在子树\(v\)中,dfs序直接走起,变成判断是否存在\(i\)使得:\[in_x\lein_{p_i}\leout_x,l\lei\ler\]二维数点,启动!代码:#include<bits/stdc++.h>usingnamespacestd;#defi......