ACM模版

描述

题解

贪心,没什么难的,就是尽可能的匹配到覆盖率高的区间。先对广告进行排序,按照左端点从小到大,右端点从大到小的主次关系来排序,这时,排好的序列中右端点的图像是锯齿形的,我们只取一个单调递增的子序列进行匹配,因为这样我们就能匹配到最大的区间。然后呢,我们根据每一个频道的需求,查找小于 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;
}