首页 > 其他分享 >CF EDU 97 E - Make It Increasing

CF EDU 97 E - Make It Increasing

时间:2022-08-14 19:00:52浏览次数:69  
标签:include int Make CF len INF Increasing

LIS

E - Make It Increasing

题意

给定数组 $a $, (n <= 5e5), 有一个集合 b ,b 里面存的是 a 数组的某些下标,这些位置的 a 的值不能改变

其余位置可花 1 代价变为任意一个整数,求让 a 变成严格单调递增的最小代价;若不可以则输出 -1

思路

有个套路是若让数组是严格单调递增的,可以令 \(a_i=a_i-i\), 之后把 \(a\) 变成非严格单调递增就可满足原来的 a 是严格单调递增的

这样就可以把数组分为若干区间,每个区间的两端是不能改变的位置,设两端下标为 l, r

  1. 若 \(a[l] >a[r]\), 则可直接输出 -1
  2. 若\(a[l]<=a[r]\), 则把 [l+1, r - 1] 这些位置的数,在 \([a[l], a[r]]\) 范围内的数求一个 LIS,就是最多的不用改变的数,再求每个区间的最小代价

有个小技巧是可以令 a[0] = -INF, a[n+1] = INF, 分别作为第一个区间的左端点,最后一个区间的右端点,这样可以不用特判

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>

using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;


const int N = 5e5 + 10;
const int INF = 2e9;
int n, k;
int a[N], b[N], c[N], f[N];


int LIS(int a[], int n)
{
	if (n == 0)
		return 0;
	f[1] = a[1];
	int len = 1;
	for (int i = 2; i <= n; i++)
	{
		if (a[i] >= f[len])
			f[++len] = a[i];
		else
		{
			int idx = upper_bound(f + 1, f + len + 1, a[i]) - f;
			f[idx] = a[i];
		}
	}
	return len;
}
int calc(int l, int r)
{
	int idx = 0;
	int L = a[l], R = a[r];
	for (int i = l + 1; i < r; i++)
	{
		if (a[i] >= L && a[i] <= R)
			c[++idx] = a[i];
	}
	return r - l - 1 - LIS(c, idx);
}
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> k;
	for (int i = 1, x; i <= n; i++)
	{
		cin >> x;
		a[i] = x - i;
	}
	for (int i = 1; i <= k; i++)
		cin >> b[i];
	b[0] = 0, b[k+1] = n + 1;
	a[0] = -INF, a[n+1] = INF;
	int ans = 0;
	for (int i = 1; i <= k + 1; i++)
	{
		int l = b[i-1], r = b[i];
		if (a[l] > a[r])
		{
			cout << -1 << endl;
			return 0;
		}
		ans += calc(l, r);
	}
	cout << ans << endl;
    return 0;
}

标签:include,int,Make,CF,len,INF,Increasing
From: https://www.cnblogs.com/hzy717zsy/p/16586051.html

相关文章

  • CF986C AND Graph(图论+二进制连边)
    CF986CANDGraph\(\color{yellow}{\bigstar\texttt{Hint}}\):和每个点连接的点是这个数取反后的子集,考虑将这个点和它的反连边,那么所有对应的数的子集都是同一个连通块内......
  • CF559E Gerald and Path(DP)
    CF559EGeraldandPath设\(dp(i,p)\)表示完成前\(i\)条线段的覆盖,最右端位于\(p\)点的最大收益。转移?向下一条线段转移时加上他们中间的距离?发现这样没有办法统计......
  • CF856D Masha and Cactus(树上 DP+抵消贡献技巧)
    CF856DMashaandCactus我们先捞出一个根节点,那么一次旋变就是对路径上点的覆盖。设\(dp_{i,0}\)表示\(i\)没有选择时子树内最大收益,\(dp_{i,1}\)表示\(i\)选择......
  • CF464E The Classic Problem(线段树 最短路)
    CF464ETheClassicProblem\(\bigstar\texttt{Hint}\):发现没有什么好的突破口?为什么不想想怎样才能实现题目中\(2^x\)的加减法呢?可见每次加减法,我们要做的是将添加的......
  • CF512D Fox And Travelling(DP 计数)
    CF512DFoxAndTravelling给定一张\(n\)个点\(m\)条边的无向图,每次选择一个叶子结点并将它和连接它的边删除。对于每个\(k\in[0,n]\),问有序选择\(k\)个点的方案......
  • CF EDU 131 D - Permutation Restoration
    贪心、扫描线思想D-PermutationRestoration题意有\(1-n\)的一个排列\(a_i\),给定\(b_i\),满足\(b_i=\lfloor\fraci{a_i}\rfloor\),求\(a_i\)(n<=5e5)......
  • CF722E Research Rover
    ResearchRoverCF722E(Luogu)题面翻译有一个n*m的网格图,图中有k个特殊点。初始时你有一个权值s,并且只能向下或向右走,每经过一个特殊点会使得你的权值/2(向上取整)。......
  • Visual Studio 部署连接至远端 WSL 的 CMake 环境
    需求虽然CMAKE是"跨平台"的,但是这实际上说的是API的问题,我这里的需求不涉及多套API的问题,我只会使用"跨开发平台"这一点。也即是交叉编译,在Windows下开发Lin......
  • Makefile入门
    1.Makefile引入简单编译C文件时一般用的gcc:gcc-otesta.cb.c。但是当项目变得十分庞大时,逐个文件编译,效率极低。这时候必须引入Makefile作为编译管理。当项目设计诸......
  • CF1712题解(E,F)
    E题意是让你求满足\(lcm(i,j,k)\geqi+j+k\)的三元组个数。我们通常都有一个直观感觉,lcm应该是各数之积级别的,换句话说,不满足\(lcm(i,j,k)\geqi+j+k\)的三元组个数......