首页 > 其他分享 >CodeForces 1965F Conference

CodeForces 1965F Conference

时间:2024-05-22 22:51:44浏览次数:25  
标签:Conference typedef 1965F ll CodeForces long 合法 maxn define

洛谷传送门

CF 传送门

考虑题目可以看成天和人的匹配,因此判断单个日期区间 \([l, r]\) 可以考虑 Hall 定理,设 \(N(S)\) 为在 \(S\) 这些天有空的人的数量,定义 \(S\) 合法当且仅当 \(|N(S)| \ge |S|\),那么 \([l, r]\) 合法当且仅当 \(\forall S \subseteq [l, r]\),\(S\) 合法。

猜测只用 check 形成一段区间的 \(S\),但是会被下面的数据叉掉:

3
1 3
2 2
2 2

对于 \([1, 3]\),只有 \(\{1, 3\}\) 不合法。

因此考虑对初始的线段进行一些处理。发现对于两条线段 \([a, b]\) 和 \([a, c]\)(其中 \(b \le c\)),把它们换成 \([a, b], [a + 1, c]\) 不影响结果(特别地,若 \(a = b = c\) 则相当于删去 \([a, c]\) 这条线段)。这部分实现可以扫描线,枚举 \(l\),把最小且 \(\ge l\) 的右端点 \(r\) 和 \(l\) 形成的线段 \([l, r]\) 加入。

处理后每个人的线段的左端点互不相同,这时候就只用 check 形成一段区间的 \(S\) 了,因为若 \(|N(S)| < |S|\) 且 \(\exists x, y \in S\) 使得 \([x + 1, y - 1]\) 都不属于 \(S\),那么加入 \([x + 1, y - 1]\) 后 \(|N(S)| < |S|\) 仍然满足,因为每加一个数 \(|N(S)|\) 至多增加 \(1\)。

所以此时不合法区间满足单调性,即若 \([l, r]\) 不合法,那么 \([l - 1, r], [l, r + 1]\) 都不合法。

所以可以双指针求出,对于每个 \(l\) 最大的 \(r\),使得 \([l, r]\) 合法(\([l, r + 1]\) 不合法)。

最后差分统计一下即可。

时间复杂度 \(O((n + V) \log n)\)。

code
// Problem: F. Conference
// Contest: Codeforces - Codeforces Round 941 (Div. 1)
// URL: https://codeforces.com/problemset/problem/1965/F
// Memory Limit: 512 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;

ll n, m, b[maxn], c[maxn], d[maxn], ans[maxn];
vector<ll> vc[maxn];

struct node {
	ll l, r;
	node(ll a = 0, ll b = 0) : l(a), r(b) {}
} a[maxn];

void solve() {
	scanf("%lld", &n);
	ll nn = n;
	for (int i = 1; i <= n; ++i) {
		scanf("%lld%lld", &a[i].l, &a[i].r);
		m = max(m, a[i].r);
	}
	priority_queue< ll, vector<ll>, greater<ll> > pq;
	for (int i = 1; i <= n; ++i) {
		vc[a[i].l].pb(a[i].r);
	}
	n = 0;
	for (int i = 1; i <= m; ++i) {
		for (int j : vc[i]) {
			pq.push(j);
		}
		while (pq.size() && pq.top() < i) {
			pq.pop();
		}
		if (pq.size()) {
			a[++n] = node(i, pq.top());
			pq.pop();
		}
	}
	for (int i = 1; i <= n; ++i) {
		b[a[i].l] = a[i].r;
		++c[a[i].r];
		++d[a[i].l];
		--d[a[i].r + 1];
	}
	int s = 0;
	for (int i = m, j = m; i; --i) {
		s += c[i];
		while (j >= i && s < j - i + 1) {
			s -= (b[j] ? 1 : 0);
			--j;
		}
		if (j <= m) {
			++ans[j - i + 1];
		}
	}
	for (int i = max(m, nn); i; --i) {
		ans[i] += ans[i + 1];
	}
	for (int i = 1; i <= nn; ++i) {
		printf("%lld\n", ans[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:Conference,typedef,1965F,ll,CodeForces,long,合法,maxn,define
From: https://www.cnblogs.com/zltzlt-blog/p/18207311

相关文章

  • Codeforces 1974G Money Buys Less Happiness Now
    考虑到有一种贪心的思路就是能选就选。显然这是错的,因为可能存在后面更优的情况,即当\(c_i>c_j(i<j)\)时,选\(j\)肯定比选\(i\)更优,因为后面剩下的更多且中间也留下了一些。于是考虑反悔贪心。还是一样的,如果能选就一定选上。否则来说,考虑对于当前已经选了的中的最大......
  • Codeforces Round 946 (Div. 3)
    CodeforcesRound946(Div.3)总结:赛时状态很好,做出了感觉平常会赛时寄掉但是赛后补题的E,但是也因此花费时间太多,没时间去做更简单的F和G,赛后G用时十分钟AC,F码的有点麻烦,用时40分钟左右,感觉三个小时能AK?A.PhoneDesktop题意:给定3*5的平面,有a个1*1的格子和b个2*2的格子,求完全......
  • Codeforces Round 945 (Div. 2) (A - E)
    A每一轮对总分的贡献都是\(2\),如果\(p_1+p_2+p_3\)为奇数则无解。\(p_1+p_2\lep_3\),最多\(p_1+p_2\)轮。\(p_1+p_2>p_3\),可以\(1,2\)轮流将\(3\)耗完,然后互相匹配,最多\(\dfrac{p_1+p_2+p_3}{2}\)。B如何判断一个\(k_0\)是否符合条件?处......
  • Codeforces 401B Sereja and Contests 题解
    题目简述Sereja是一名程序员,他喜欢参加Codesorfes比赛。不过,乌兹兰的网络连接不太好,所以Sereja有时会跳过比赛。Codesorfes有两种类型的比赛,分为Div1和Div2。Div1和Div2这两轮可以同时进行(Div1轮不能在没有Div2的情况下进行)。每一轮都有一个唯一的标识符,各轮按......
  • Codeforces Round 944 (Div. 4)
    CodeforcesRound944(Div.4)需要一些trick的一场H:2-sat的板子,已经计入2-sat专题,此处不再详细描述。题目用矩阵包装和博弈包装,我们需要慢慢读题,分析样例,找到问题的关键点。G:题意:给定一个数组,数组中任何两个数异或<4的数对可以交换位置,可以交换无限次,求能够形成的字典序最......
  • Codeforces Round 945 (Div. 2) A-D
    A.ChessForThree模拟。首先可以发现每一次对局三人的得分总和加\(2\),所以若干次对局后得分总和也一定是\(2\)的倍数,然后为了使和棋数量尽可能多,一直让得分最高的两人和棋且得分数各减\(1\)直到无法做出和棋为止。#include<bits/stdc++.h>usingnamespacestd;#def......
  • Codeforces Round 945 (Div. 2)
    A-ChessForThree因为序列满足a<=b<=c的情况显然通过得分可以观察出得分总和必定为偶数否则不成立求的是最大平局数那么直接假设全部都是平局这时候发现如果c过大会导致后面的局数不是平局那么只用把c>a+b的情况取出而此时平均数为a+b点击查看代码#include<bits/stdc+......
  • Codeforces 769B News About Credit 题解
    题目简述波利卡普在由$n$名学生(包括他自己)组成的小组中学习,编号为$1$到$n$,波利卡普的编号始终是$1$。他们都在社交网络上注册,每个学生都有一个值$a_i$,表示第$i$名学生每天能发送的最大信息数。清晨,波利卡普知道了一个重要消息,他认为有必要通过私人消息紧急通知所有组员......
  • Codeforces 959B Mahmoud and Ehab and the message 题解
    题目简述小A想要给他的朋友小B发送了一条有$m$个单词的消息。他们的语言由编号从$a_1$到$a_n$的$n$个单词组成。一些单词具有相同的意思,因此存在$k$个单词组,其中每个组中的所有单词具有相同的意思。小A知道第$i$个单词可以以成本$m_i$发送。对于他的每个消息......
  • Codeforces 1113B Sasha and Magnetic Machines 题解
    题目简述有一个长度为$n$的正整数序列。你可以对这个数列进行最多$1$次的如下操作:选择两个数$i$和$j$,其中$1\leqi,j\leqn$并且$i\neqj$,并选择一个可以整除$a_i$的正整数$x$,然后将$a_i$变为$\frac{a_i}{x}$,将$a_j$变为$a_j\cdotx$。问你操作后,该序......