Codeforces 1555E. Boring Segments
题目大意
给你 个区间 ,每个区间覆盖其内部所有的整点,每个区间还有花费 。现在选择若干区间,问能至少覆盖 的最小代价,代价为所选区间中,花费的最大值与最小值的差。
思路
我们可以考虑在花费上进行尺取来求得最小差值,同时用线段树维护区间覆盖次数的最小值,我们每次对 或 移动时,减去/加上花费为 的区间的贡献,由于选出的区间之间必须有交集,因此处理区间时都将区间的右端点视为没有覆盖,即将原区间变为左闭右开即可解决,对于每个区间,查看是否完全覆盖了区间 即可知道是否合法,在尺取的过程中注意必须存在对应的 和 才可更新答案,复杂度 。
代码
#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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步