Educational Codeforces Round 98 (Rated for Div. 2) E. Two Editorials

题目链接
Berland regional ICPC contest has just ended. There were m m m participants numbered from 1 1 1 to m m m, who competed on a problemset of n n n problems numbered from 1 1 1 to n n n. Now the editorial is about to take place. There are two problem authors, each of them is going to tell the tutorial to exactly k k k consecutive tasks of the problemset. The authors choose the segment of k k k consecutive tasks for themselves independently of each other. The segments can coincide, intersect or not intersect at all. The i i i-th participant is interested in listening to the tutorial of all consecutive tasks from l i l_i li to r i r_i ri. Each participant always chooses to listen to only the problem author that tells the tutorials to the maximum number of tasks he is interested in. Let this maximum number be a i a_i ai. No participant can listen to both of the authors, even if their segments don’t intersect. The authors want to choose the segments of k k k consecutive tasks for themselves in such a way that the sum of a i a_i ai over all participants is maximized. Input
The first line contains three integers n , m n, m n,m and k k k ( 1 ≤ n , m ≤ 2000 1 \le n, m \le 2000 1n,m2000, 1 ≤ k ≤ n 1 \le k \le n 1kn) — the number of problems, the number of participants and the length of the segment of tasks each of the problem authors plans to tell the tutorial to. The i i i-th of the next m m m lines contains two integers l i l_i li and r i r_i ri ( 1 ≤ l i ≤ r i ≤ n 1 \le l_i \le r_i \le n 1lirin) — the segment of tasks the i i i-th participant is interested in listening to the tutorial to. Output
Print a single integer — the maximum sum of a i a_i ai over all participants. Examples
input

10 5 3
1 3
2 4
6 9
6 9
1 8

output

14

input

10 3 3
2 4
4 6
3 5

output

8

input

4 4 1
3 3
1 1
2 2
4 4

output

2

input

5 4 5
1 2
2 3
3 4
4 5

output

8

Note
In the first example the first author can tell the tutorial to problems from 1 1 1 to 3 3 3 and the second one — from 6 6 6 to 8 8 8. That way the sequence of a i a_i ai will be [ 3 , 2 , 3 , 3 , 3 ] [3, 2, 3, 3, 3] [3,2,3,3,3]. Notice that the last participant can’t listen to both author, he only chooses the one that tells the maximum number of problems he’s interested in. In the second example the first one can tell problems 2 2 2 to 4 4 4, the second one — 4 4 4 to 6 6 6. In the third example the first one can tell problems 1 1 1 to 1 1 1, the second one — 2 2 2 to 2 2 2. Or 4 4 4 to 4 4 4 and 3 3 3 to 3 3 3. Every pair of different problems will get the same sum of 2 2 2. In the fourth example the first one can tell problems 1 1 1 to 5 5 5, the second one — 1 1 1 to 5 5 5 as well.
在这里插入图片描述

如图所示,这是某参与者选择两各时间段均可的情况。显然,当某参与者与两个时间段都有交集的时候,该参与者的时间段的中点与哪个时间段更近则更应该选择哪个时间段。因为最优情况一定是中点靠后的在后一个时间段,中点靠前的在前一个时间段,因此考虑枚举参与者参加前一段和后一段的分界线,首先将所有参与者的时间段按照中点排序,然后暴力 O ( n m ) O(nm) O(nm) 求出后 m − i + 1 m-i+1 mi+1 个参与者在只有一个时间段的情况下最大的总人次 s u m 1 [ i ] sum1[i] sum1[i] 。同理可求出求前 i i i 个参与者在只有一个时间段的情况下最大的总人次 s u m 2 [ i ] sum2[i] sum2[i] 。最终的答案为 max ⁡ i = 1 m ( s u m 1 [ i ] + s u m 2 [ i + 1 ] ) \max\limits_{i=1}^m(sum1[i]+sum2[i+1]) i=1maxm(sum1[i]+sum2[i+1]) 。时间复杂度为 O ( n log ⁡ n + n m ) O(n\log n+nm) O(nlogn+nm)

#include<bits/stdc++.h>

using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 2e3 + 10;
int n, m, k;

struct node {
    int l, r;

    inline bool operator<(node a) const {
        return l + r < a.l + a.r;
    }
} a[N];

int sum[N];

int main() {
    n = qr(), m = qr(), k = qr();
    for (int i = 1; i <= m; ++i)a[i].l = qr(), a[i].r = qr();
    sort(a + 1, a + 1 + m);
    for (int l = 1; l <= n - k + 1; ++l) {
        int r = l + k - 1;
        int cur = 0;
        for (int i = m; i >= 1; --i) {
            cur += max(0, min(r, a[i].r) - max(l, a[i].l) + 1);
            sum[i] = max(sum[i], cur);
        }
    }
    int ans = 0;
    for (int l = 1; l <= n - k + 1; ++l) {
        int r = l + k - 1;
        int cur = 0;
        for (int i = 1; i <= m; ++i) {
            cur += max(0, min(r, a[i].r) - max(l, a[i].l) + 1);
            ans = max(ans, cur + sum[i + 1]);
        }
    }
    printf("%d\n", ans);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_sky123_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值