描述
题解
贪心,没什么难的,就是尽可能的匹配到覆盖率高的区间。先对广告进行排序,按照左端点从小到大,右端点从大到小的主次关系来排序,这时,排好的序列中右端点的图像是锯齿形的,我们只取一个单调递增的子序列进行匹配,因为这样我们就能匹配到最大的区间。然后呢,我们根据每一个频道的需求,查找小于 aj 的第一个区间位置(二分),然后遍历其后紧挨着的合法的区间,求最值即可。
这个题不难,就是题目读起来十分佶屈聱牙,静下心来分析就会发现这是一个多么简单的贪心啊!
代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 10;
template <class T>
inline void scan_d(T &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}
struct node
{
int l, r, pos;
} ad[MAXN], tp[MAXN];
int n, m;
int tot = 0;
ll ans;
int tmp[MAXN];
bool cmp(node a, node b)
{
return a.l < b.l || (a.l == b.l && a.r > b.r);
}
int main()
{
scan_d(n), scan_d(m);
for (int i = 1; i <= n; i++)
{
scan_d(ad[i].l);
scan_d(ad[i].r);
ad[i].pos = i;
}
sort(ad + 1, ad + n + 1, cmp);
tp[++tot] = ad[1];
tmp[tot] = ad[1].l;
for (int i = 2; i <= n; i++)
{
if (ad[i].r > tp[tot].r)
{
tp[++tot] = ad[i];
tmp[tot] = ad[i].l;
}
}
int a, b, c;
for (int i = 1; i <= m; i++)
{
scan_d(a), scan_d(b), scan_d(c);
int p = (int)(lower_bound(tmp + 1, tmp + tot + 1, a) - tmp - 1);
for (; p <= tot && tp[p].l <= b; p++)
{
ll val = (ll)(min(tp[p].r, b) - max(tp[p].l, a)) * c;
if (val > ans)
{
ans = val;
}
}
}
printf("%lld\n", ans);
return 0;
}