CF1965F Conference
记录一个自己切掉的 *3300。
首先注意到这是个匹配问题,根据形式很容易想到 hall 定理。乍一看认为对于一段区间的判定只需要判定所有子串就行了。
下面合法相当于是 hall 定理中的
考虑这个怎么判,我先考虑了对于一个段
每个右端点
其中
那么我们对任意
交上去,发现第二十九个点 WA 了,以为写锅了,但经过检查发现并没有锅。
再进行一段时间的思考发现,不合法的集合并不一定是连续的一段!没事,冷静思考不要慌,分析造成这种情况的原因。令
显然我们存在很多讲课时间段都是多余的,我们考虑保留有用的段。我们发现在判定时如果我们考虑到了
然后就做完了,时间复杂度
代码:
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i (l); i <= (r); ++ i)
#define rrp(i, l, r) for (int i (r); i >= (l); -- i)
#define pii pair <int, int>
#define eb emplace_back
#define ls p << 1
#define rs ls | 1
using namespace std;
constexpr int N = 2e5 + 5, B = 71, P = 1042702009;
typedef unsigned long long ull;
inline int rd () {
int x = 0, f = 1;
char ch = getchar ();
while (! isdigit (ch)) {
if (ch == '-') f = -1;
ch = getchar ();
}
while (isdigit (ch)) {
x = (x << 1) + (x << 3) + ch - 48;
ch = getchar ();
}
return x * f;
}
int qpow (int x, int y) {
int ret = 1;
for (; y; y >>= 1, x = x * x % P) if (y & 1) ret = ret * x % P;
return ret;
}
int n, m, pre[N], suf[N];
vector <int> vec[N];
int diff[N];
int f[N][23];
int qry (int l, int r) {
int k = __lg (r - l + 1);
return max (f[l][k], f[r - (1 << k) + 1][k]);
}
int main () {
// freopen ("1.in", "r", stdin);
// freopen ("1.out", "w", stdout);
n = 2e5; m = rd (); int cm = m;
rep (i, 1, m) {
int l = rd (), r = rd ();
vec[l].eb (r);
// ++ pre[r], ++ suf[l];
}
priority_queue <int> q;
m = 0;
rep (i, 1, n) {
for (auto j : vec[i]) q.push (- j);
vec[i].clear ();
while (! q.empty () && - q.top () < i) q.pop ();
if (! q.empty ()) {
++ pre[- q.top ()], q.pop (), ++ suf[i], ++ m;
}
}
rep (i, 1, n) -- pre[i];
rep (i, 0, n) pre[i] += pre[i - 1], f[i][0] = pre[i];
rep (j, 1, 22) {
rep (i, 0, n - (1 << j) + 1) f[i][j] = max (f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
rrp (i, 1, n) suf[i] += suf[i + 1];
rep (i, 1, n) {
int l = 1, r = i;
while (l <= r) {
int mid = l + r >> 1;
if (qry (mid, i) <= m - suf[i + 1] - i) {
r = mid - 1;
} else l = mid + 1;
}
if (pre[r] > m - suf[i + 1] - i) vec[r + 1].eb (i);
}
int r = 2e5 + 1;
rrp (i, 1, n) {
for (auto u : vec[i]) r = min (r, u);
++ diff[1]; -- diff[r - i + 1];
}
rep (i, 1, m) {
diff[i] += diff[i - 1];
printf ("%d\n", diff[i]);
}
rep (i, m + 1, cm) puts ("0");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?