Live2D

Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份

Description

  Link.

  给定升序序列 {xn} 以及整数 k,在 {xn} 中选出恰 k(xi,xj),使得不存在某个值出现次数多于一次,并最小化 |xixj|

Solution

  告诉我,你有一个错误的贪心 owo!

  显然 (xi,xj) 是相邻的两个数。令 ai=xi+1xi,问题转化为选 kai 使其和最小,并保证 ai 被选后 ai1ai+1 不被选。

  贪心取最小是不可取的,样例就是反例。不过可以使用网络流退流的思想挽救这个贪心。每次取出最小值 ai 时,将 ai 的值置为 ai1+ai+1ai 并重新入堆,同时删除在序列上 ai1ai+1(这里的下标加减法指前驱后继,因为有些数已经被删掉了)。考虑再次选择 ai 时所表达的方案:

  初始:

ai2    ai1    ai    ai+1    ai+2

  选 ai,此时答案 ans=ai;并重置 ai,删前驱后继:

ai2    ai1    ai1+ai+1ai    ai+1    ai+2

  再选 ai,此时答案 ans=ai+ai1+ai+1ai=ai1+ai+1,再重置,删除:

ai2    ai1    ai2+ai+2ai1ai+1+ai    ai+1    ai+2

  可以发现,这与直接选 ai2ai+2 是等效的!所以维护一个双向链表,利用堆进行贪心即可。

  复杂度 O(nlogn)

Code

#include <queue>
#include <cstdio>

typedef long long LL;
typedef std::pair<LL, int> pli;

const int MAXN = 1e5;
int n, K, pre[MAXN + 5], suf[MAXN + 5];
LL val[MAXN + 5];
bool rmd[MAXN + 5];
std::priority_queue<pli, std::vector<pli>, std::greater<pli> > heap;

inline int rint () {
	int x = 0; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () );
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
	return x;
}

inline void rmpos ( const int u ) {
	if ( ! u || u == n ) return ;
	rmd[u] = true;
	if ( pre[u] ) suf[pre[u]] = suf[u];
	if ( suf[u] ^ n ) pre[suf[u]] = pre[u];
	pre[u] = suf[u] = 0;
}

int main () {
	n = rint (), K = rint ();
	for ( int i = 0, p, las; i < n; ++ i ) {
		p = rint ();
		if ( i ) {
			heap.push ( { val[i] = p - las, i } );
			pre[i] = i - 1, suf[i] = i + 1;
		}
		las = p;
	}
	LL ans = 0;
	val[0] = val[n] = 1ll << 60;
	while ( K -- ) {
		pli t = heap.top (); heap.pop ();
		if ( rmd[t.second] ) { ++ K; continue; }
		ans += t.first; LL nv = -t.first;
		nv += val[pre[t.second]], rmpos ( pre[t.second] );
		nv += val[suf[t.second]], rmpos ( suf[t.second] );
		heap.push ( { val[t.second] = nv, t.second } );
	}
	printf ( "%lld\n", ans );
	return 0;
}
posted @   Rainybunny  阅读(88)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示