CF1842E Tenzing and Triangle 题解

题意不多赘述。

思路

如果两个所选的三角形有重合部分的话,那么这种情况肯定是不会出现的。因为如果把这两个三角形合成一个大三角形的话,不仅覆盖面积会增大,而且花费的代价还不会多。

于是我们可以想到用 dp 来解决,设 \(dp_{i}\) 表示删完横坐标为 \(0\)\(i\) 中的点的最小代价,很容易得到状态转移方程:\(dp_{i}=\min(dp_{j}+(i-j-1)\times A+cost)\)。这里的 \(cost\) 指的是所有满足 \(j<x\le i,1\le y<k-i\) 的条件的点,因为只有这些点没有被当前所选的这个三角形所包含,所以需要加上这些点的代价。但是这个方程转移的时间复杂度是 \(O(n^{2})\) 的,所以还需要优化。

我们可以发现一些性质,首先方程中的 \(A\times(i-j-1)\) 一定是递减的,而 \(cost\) 值的变化也有一些规律。从 \(i\) 变到 \(i+1\) 的过程中,需要加上满足 \(x=i\) 的点的代价,减去满足 \(y=k-i\) 的点的代价,其余的点不会变化。所以我们发现每一次从 \(i\) 变为 \(i+1\) 我们都可以只修改之前所有 \(A\)\(cost\) 的值就行了,每一次的值就是前面所有数的最小值,而这两个操作都可以用线段树来维护,时间复杂度 \(O(n \log n)\)。注意线段树维护的每一个 \(j\) 的值已经是 \(dp_{j}+(i-j-1)\times A+cost\) 了,所以直接查询最小值就可以了。

注意因为坐标轴的最小值为 \(0\),所以我们还需要维护一个下标为 \(-1\) 的值,这个值代表前面还什么都没有选时的代价。

Code

#include<bits/stdc++.h>
using namespace std; 
#define int long long
#define inf 0x3f
#define inf_db 127
#define ls id << 1
#define rs id << 1 | 1
#define re register
#define endl '\n'
typedef pair <int,int> pii;
const int MAXN = 1e6 + 10;
int n,x,y,c,cost[MAXN],k,A,dp[MAXN];
struct SegmentTree{int id,l,r,mn,add;}tree[MAXN];
inline void Pushup(int id){tree[id].mn = min(tree[ls].mn,tree[rs].mn);}
inline void Build(int id,int l,int r)
{
	tree[id].l = l,tree[id].r = r;
	if(l == r){tree[id].mn = 0;return;}
	int mid = (l + r) >> 1;
	Build(ls,l,mid),Build(rs,mid + 1,r);
}
inline void Pushdown(int id)
{
	if(tree[id].add == 0) return;
	tree[ls].mn += tree[id].add,tree[ls].add += tree[id].add;
	tree[rs].mn += tree[id].add,tree[rs].add += tree[id].add;
	tree[id].add = 0;
}
inline void Add(int id,int l,int r,int a,int b,int c)
{
	if(a <= l && b >= r)
	{
		tree[id].mn += c;
		tree[id].add += c;
		return;
	}
	Pushdown(id);
	int mid = (l + r) >> 1;
	if(a <= mid) Add(ls,l,mid,a,b,c);
	if(b > mid) Add(rs,mid + 1,r,a,b,c);
	Pushup(id);
}
inline int Query(int id,int l,int r,int a,int b)
{
	if(a <= l && b >= r) return tree[id].mn;
	Pushdown(id);
	int mid = (l + r) >> 1,res = 1e18;
	if(a <= mid) res = min(res,Query(ls,l,mid,a,b));
	if(b > mid) res = min(res,Query(rs,mid + 1,r,a,b));
	return res;
}
std::vector <pii> a[MAXN];
signed main()
{
	cin >> n >> k >> A;
	Build(1,-1,k);
	for(int i = 1;i <= n;i++)
	{
		cin >> x >> y >> c;
		a[y].emplace_back(x,c);
		if(x + y != k) cost[x] += c;
	}
	for(int i = 0;i <= k;i++)
	{
		for(int j = 0;j < a[k - i].size();j++) Add(1,-1,k,-1,a[k - i][j].first - 1,-a[k - i][j].second);
		Add(1,-1,k,-1,i - 1,cost[i]);
		if(i != 0) Add(1,-1,k,-1,i - 2,A);
		dp[i] = Query(1,-1,k,-1,i - 1),Add(1,-1,k,i,i,dp[i]);
	}
	cout << dp[k]; 
	return 0;
}		
posted @ 2023-12-11 12:23  Creeper_l  阅读(10)  评论(0编辑  收藏  举报
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 世间美好与你环环相扣 柏松
  3. 3 True love tired
  4. 4 一笑江湖 (DJ弹鼓版) 闻人听書_
  5. 5 最好的安排 曲婉婷
  6. 6 星星在唱歌 司南
  7. 7 山川 李荣浩
  8. 8 On My Way Alan Walker
  9. 9 百战成诗 王者荣耀·100英雄官方群像献礼歌
  10. 10 雪 Distance Capper / 罗言
  11. 11 Edamame bbno$ / Rich Brian
  12. 12 半生雪 七叔-叶泽浩
  13. 13 Catch My Breath Kelly Clarkson
  14. 14 Love Is Gone SLANDER / Dylan Matthew
  15. 15 Endless Summer Alan Walker / Zak Abel
  16. 16 悬溺 葛东琪
  17. 17 风吹丹顶鹤 葛东琪
  18. 18 Normal No More TYSM
  19. 19 哪里都是你 队长
  20. 20 Stronger Kelly Clarkson
  21. 21 廖俊涛
  22. 22 消愁 毛不易
  23. 23 The Runner Yubik
  24. 24 踏山河 七叔-叶泽浩
  25. 25 Waiting For Love Avicii
  26. 26 在你的身边 盛哲
  27. 27 Dream It Possible Delacey
  28. 28 凄美地 郭顶
  29. 29 满天星辰不及你 ycc
  30. 30 侧脸 于果
  31. 31 阿拉斯加海湾 蓝心羽
  32. 32 虞兮叹 闻人听書_
  33. 33 离别开出花 就是南方凯
  34. 34 盗墓笔记·十年人间 李常超 (Lao乾妈)
盗墓笔记·十年人间 - 李常超 (Lao乾妈)
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.