2022-07-27 21:56阅读: 26评论: 0推荐: 0

Codeforces 1555E. Boring Segments

Difficulty:2100

题目大意

给你 n(1n3105) 个区间 [l,r](1lrm) ,每个区间覆盖其内部所有的整点,每个区间还有花费 w(1w106) 。现在选择若干区间,问能至少覆盖 1m(2m106) 的最小代价,代价为所选区间中,花费的最大值与最小值的差。

思路

我们可以考虑在花费上进行尺取来求得最小差值,同时用线段树维护区间覆盖次数的最小值,我们每次对 ij 移动时,减去/加上花费为 i/j 的区间的贡献,由于选出的区间之间必须有交集,因此处理区间时都将区间的右端点视为没有覆盖,即将原区间变为左闭右开即可解决,对于每个区间,查看是否完全覆盖了区间 [1,m1] 即可知道是否合法,在尺取的过程中注意必须存在对应的 ij 才可更新答案,复杂度 O(nlogn)

代码

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using LL = long long;
using LD = long double;
using ULL = unsigned long long;
using PII = pair<int, int>;
using TP = tuple<int, int, int>;
#define all(x) x.begin(),x.end()
#define mst(x,v) memset(x,v,sizeof(x))
#define mul(x,y) (1ll*(x)*(y)%mod)
#define mk make_pair
//#define int LL
//#define double LD
#define lc p*2
#define rc p*2+1
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const double pi = acos(-1);
const LL MOD = 1000000007;
const LL mod = 1004535809;
const int maxn = 1000010;

int N, M, mx = 0;
vector<PII>s[maxn];
struct Node {
	int dat, l, r, lazy;
}tr[maxn * 4];

void pushup(int p)
{
	tr[p].dat = min(tr[lc].dat, tr[rc].dat);
}

void pushdown(int p)
{
	if (tr[p].lazy)
	{
		tr[lc].dat += tr[p].lazy, tr[rc].dat += tr[p].lazy;
		tr[lc].lazy += tr[p].lazy, tr[rc].lazy += tr[p].lazy;
		tr[p].lazy = 0;
	}
}

void build(int p, int l, int r)
{
	tr[p].l = l, tr[p].r = r;
	if (l + 1 == r)
	{
		tr[p].dat = 0;
		return;
	}
	int mid = (l + r) / 2;
	build(lc, l, mid), build(rc, mid, r);
	pushup(p);
}

void modify(int p, int l, int r, int v)
{
	if (tr[p].l >= l && tr[p].r <= r)
	{
		tr[p].dat += v, tr[p].lazy += v;
		return;
	}
	int mid = (tr[p].l + tr[p].r) / 2;
	pushdown(p);
	if (l < mid)
		modify(lc, l, r, v);
	if (r > mid)
		modify(rc, l, r, v);
	pushup(p);
}

int query(int p, int l, int r)
{
	if (tr[p].l >= l && tr[p].r <= r)
		return tr[p].dat;
	int mid = (tr[p].l + tr[p].r) / 2;
	pushdown(p);
	if (r <= mid)
		return query(lc, l, r);
	if (l >= mid)
		return query(rc, l, r);
	return min(query(lc, l, mid), query(rc, mid, r));
}

void solve()
{
	int ans = inf, j = 0;
	build(1, 1, M);
	for (int i = 1; i <= mx; i++)
	{
		while (true)
		{
			if (query(1, 1, M) > 0)
				break;
			j++;
			if (j == mx + 1)
				break;
			for (auto& [x, y] : s[j])
				modify(1, x, y, 1);
		}
		if (j == mx + 1)
			break;
		if (s[i].size() && s[j].size())
			ans = min(ans, j - i);
		for (auto& [x, y] : s[i])
			modify(1, x, y, -1);
	}
	cout << ans << endl;
}

int main()
{
	IOS;
	cin >> N >> M;
	int l, r, w;
	for (int i = 1; i <= N; i++)
		cin >> l >> r >> w, s[w].push_back(PII(l, r)), mx = max(mx, w);
	solve();

	return 0;
}

本文作者:Prgl

本文链接:https://www.cnblogs.com/Prgl/p/16526679.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Prgl  阅读(26)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开