好题啊!
考虑一个经典套路。
若一个人不会,则她的分数 ,否则她的分数 。
转化问题。
首先一个人的分数 ,若她会,则她的分数 。
此时考虑两个人 ,。对于问题 :
- 和 都不会问题 。则相对贡献为 。
- 和 都会问题 。则相对贡献为 。
- 会问题 , 不会问题 ,则相对贡献为 。
- 会问题 , 不会问题 ,则相对贡献为 。
因而若 和 两个人贡献了极差,且 的分数不低于 的分数,则令 会的问题集合为 , 会的问题集合为 ,则答案为 。问题变为找到两个人 , 满足 的值最大。
枚举 表示令 ,则考虑计算 ()时对答案的贡献。
- 被 完全包含。此时 长度固定,因此 的长度越短越好。
- 被 完全包含。
这还打个【数据删除】? - 在 左侧。显然最小化答案需要让两个集合的交尽量小。因此需要让 的右端点尽量小。
- 在 右侧。显然最小化答案需要让两个集合的交尽量小。因此需要让 的左端点尽量大。
分三类讨论,时间复杂度为 或 ,可以简单通过。
代码:
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define eb emplace_back
#define int long long
using namespace std;
const int N = 1000100;
const int mod = 998244353;
const int base = 256;
const int inf = 0x0d000721ll << 2 | 0xAC66666;
int read() {
int o = 1, x = 0;
char ch;
while (!isdigit(ch = getchar())) {
if (ch == '-') {
o = -o;
}
}
x = ch & 15;
while (isdigit(ch = getchar())) {
x = (x << 3) + (x << 1) + (ch & 15);
}
return x * o;
}
int l[N], r[N];
signed main() {
int T;
T = read();
while (T--) {
int n, m;
n = read(), m = read();
int L = -inf, R = inf;
int mx = -inf, mlen = inf;
for (int i = 1; i <= n; ++i) {
l[i] = read(), r[i] = read();
L = max(L, l[i]);
R = min(R, r[i]);
mlen = min(mlen, r[i] - l[i] + 1);
}
for (int i = 1; i <= n; ++i) {
mx = max({mx, (r[i] - l[i] + 1 - min({max(0ll, R - l[i] + 1), max(0ll, r[i] - L + 1), mlen}) << 1)});
}
cout << mx << '\n';
}
return 0;
}
/*
*/
喜欢的话,留下你的评论吧~