首页 > 其他分享 >Educational Codeforces Round 150 (Rated for Div. 2) 题解

Educational Codeforces Round 150 (Rated for Div. 2) 题解

时间:2023-06-13 20:22:05浏览次数:51  
标签:__ 150 Educational gnu int 题解 tree pbds include

https://codeforces.com/contest/1841

https://codeforces.com/contest/1841/problems

D. Pairs of Segments

https://codeforces.com/contest/1841/problem/D

因为 \(n\) 只有 \(2000\),所以考虑枚举每一对 \((i, j)\) 满足区间有交集并且 \(i \neq j\)。

如果有交集,就合并。

然后就是从这些合并好的区间内选出尽可能多的不交的区间。

然后 DP,设 \(f_i\) 按下标顺序选,表示最后一个区间的右端点为 \(i\) 的,最多用了多少个区间(原来的)。

设合并好的区间分别为 \([l_1', r_1'], [l_2', r_2'], \dots, [l_m', r_m']\),那么我们按右端点从大到小 DP:

\[f_{r} = \max(f_{r}, 2 + \max_{i = 0}^{l - 1} f_{i}) \]

其中 \(f_0 = 0\)。

最后答案就是所有的 \(f\) 取个 max 再用 \(n\) 减去。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
template < class Z >
inline void read (Z &tmp) {
	Z x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	tmp = !f ? x : -x;
}
int n, l[2005], r[2005], a[4005], f[4005], pre[4005];
map < int, int > mp;
set < int > st[4005];
signed main () {
	int _;
	read (_);
	while (_ --) {
		read (n);
		for (int i = 1;i <= n; ++ i) {
			read (l[i]), read (r[i]);
			a[i] = l[i], a[i + n] = r[i];
		}
		sort (a + 1, a + 1 + 2 * n);
		int m = unique (a + 1, a + 1 + 2 * n) - a - 1;
		mp.clear ();
		for (int i = 1;i <= m; ++ i) mp[a[i]] = i;
		for (int i = 1;i <= n; ++ i) l[i] = mp[l[i]], r[i] = mp[r[i]];
		for (int i = 1;i <= m; ++ i) st[i].clear ();
		for (int i = 1;i <= n; ++ i) {
			for (int j = i + 1;j <= n; ++ j) {
				if (r[i] < l[j] || r[j] < l[i]) ;
				else st[max (r[i], r[j])].insert (min (l[i], l[j]));
			}
		}
		for (int i = 0;i <= m; ++ i) f[i] = 0;
		int ans = 0;
		pre[0] = 0;
		for (int i = 1;i <= m; ++ i) {
			int now = 0;
			int siz = 0;
			for (int las : st[i]) {
				siz = 1;
				now = max (now, las - 1);
			}
			if (siz) f[i] = pre[now] + 2;
			ans = max (ans, f[i]);
			pre[i] = max (pre[i - 1], f[i]);
		}
		printf ("%d\n", n - ans);
	}
	return 0;
}
/*
Things to check:
1. int ? long long ? unsigned int ? unsigned long long ?
2. array size ? is it enough ?
*/

E. Fill the Matrix

https://codeforces.com/contest/1841/problem/E

我们把每一行的每一个极大的空白的区间取出来,排成一个序列,那么就是要取尽可能少的区间使得长度和 \(\geq m\),设取了 \(k\) 个,那么答案就是 \(m - k\)。

发现这样的区间(不考虑行号)只有 \(n\) 个,直接暴力分解然后加就行了。

然后就贪心取。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
bool Memory_Begins;
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
template < class Z >
inline void read (Z &tmp) {
	Z x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	tmp = !f ? x : -x;
}
int n, a[200005], st[200005][19], lg[200005];
ll f[200005];
ll m;
inline int query (int l, int r) {
	int k = lg[r - l + 1];
	int L = st[l][k], R = st[r - (1 << k) + 1][k];
	if (a[L] < a[R]) return L;
	else return R;
}
bool Memory_Ends;
signed main () {
	fprintf (stderr, "%.3lf MB\n", (&Memory_Begins - &Memory_Ends) / 1048576.0);
	int _; read (_);
	while (_ --) {
		int sz = 0;
		read (n);
		for (int i = 1;i <= n; ++ i) read (a[i]), a[i] = n - a[i];
		for (int i = 1;i <= n; ++ i) st[i][0] = i;
		for (int j = 1;j < 19; ++ j) {
			for (int i = 1;i + (1 << j) - 1 <= n; ++ i) {
				int L = st[i][j - 1], R = st[i + (1 << (j - 1))][j - 1];
				if (a[L] < a[R]) st[i][j] = L;
				else st[i][j] = R;
			}
		}
		lg[0] = -1;
		for (int i = 1;i <= n; ++ i) {
			lg[i] = lg[i >> 1] + 1;
		}
		read (m);
		for (int i = 1;i <= n; ++ i) f[i] = 0;
		queue < tuple < int, int, int > > q;
		q.push (make_tuple (1, n, 0));
		while (!q.empty ()) {
			tuple < int, int, int > tmp = q.front ();
			q.pop ();
			int L = get < 0 > (tmp), R = get < 1 > (tmp), w = get < 2 > (tmp);
			int u = query (L, R);
			f[R - L + 1] += a[u] - w;
			if (L < u) q.push (make_tuple (L, u - 1, a[u]));
			if (u < R) q.push (make_tuple (u + 1, R, a[u]));
		}
		ll ans = m;
		for (int i = n;i >= 1; -- i) {
			if (m >= f[i] * i) m -= f[i] * i, ans -= f[i];
			else {
				ans -= m / i;
				if (m % i) -- ans;
				break;
			}
		}
		printf ("%lld\n", ans);
	}
	fprintf (stderr, "%.3lf ms\n", 1e3 * clock () / CLOCKS_PER_SEC);
	return 0;
}
/*
Things to check:
1. int ? long long ? unsigned int ? unsigned long long ?
2. array size ? is it enough ?
*/

标签:__,150,Educational,gnu,int,题解,tree,pbds,include
From: https://www.cnblogs.com/RB16B/p/17478666.html

相关文章

  • 题解 P9196【[JOI Open 2016] 销售基因链】
    套路题,来讲个套路解法。如果没有后缀的要求,答案就是trie树的子树内字符串数量。现在加上了后缀,尝试继续使用trie树解决问题。我们建立两棵trie树\(T_1,T_2\),其中\(T_1\)是正常的trie树,\(T_2\)是每个字符串翻转后的trie树。这样的话,包含给定后缀的字符串在\(T_2\)......
  • C++ Windows.h max宏与std::max冲突问题解决
    C语言引入的宏支持了一定程度的元编程,但它仅仅是简单的字符串替换,这种“六亲不认”的操作很容易导致一些编译错误。这篇文章介绍了一种场景:项目同时引入了老的C头文件,里面用宏定义了一些宏函数;还引入了C++的头文件,里面用其他方式定义了一些同名函数。具体到问题本身,这个......
  • Not Another Linear Algebra Problem 题解
    题意:自己看。首先我们知道我们唯一能找到的题解在hos_lyric的代码里。把它放在这里:(由bikuhiku提供)\[\begin{aligned}&U\subseteq\mathbb{F}_p^n,\text{subspace}\\&a(U):=\#\{p\in\text{Aut}(\mathbb{F}_p^n)|\text{Ker}(p-\text{id})=U\}\\&b(U):=......
  • 【问题解决1】fatal error: X11/XXXX.h: No such file or directory
    问题现象编译鸿蒙代码时,报如下类似的错误:错误1:错误2:解决方法step1:安装依赖文件sudoapt-getinstallapt-filesudoapt-fileupdatestep2:查找报错文件apt-filesearchXXXX.h例如:报错的是Intrinsic.h或上图中的Xrandr.h,对应如下:apt-filesearchIntrinsic......
  • vue调用百度api时,跨域问题解决方案
    最近在调用百度地图,文字转语音接口的时候,用vue,js来前端实现转换,及时语音播报,遇到点问题;1.之前直接不用accessToken,一个连接拼接抓取的,已经失效了。2.查看百度文档,更新后的接口,按照文档nodejs格式,一直都是报跨域问题,单独在headers中加'Access-Control-Allow-Origin':'*'无效。......
  • [ABC305C] Snuke the Cookie Picker题解
    题目大意有一个\(H\timesW\)的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标。(.表示空白,#表示矩形内的点)解析观察我们可以发现,每一矩形内的个点上下左右至少会有两个是#。如图:而每一个在矩形外的点上下左右最多只有一个#。所以我们只需要找的一个.的上......
  • [ABC305D] Sleep Log题解
    题目大意给\(N\)个时刻:当\(i\)为奇数时,\(A_i\)表示刚刚起床的时刻。当\(i\)为偶数时,\(A_i\)表示开始睡觉的时刻。有\(Q\)次询问,每次求在\([l,r]\)区间内睡了多长时间。分析首先我们要考虑处理边界情况。每一次二分查找第一个大于等于\(l\)和\(r\)的时刻......
  • VM虚拟机模板,克隆或导入后网络不通问题解决办法
    出于工作需要可能需要对VM虚拟机制作模板,并导出为.vof文件,并根据vof模板文件导入为新的虚拟机,但是当导入后会发现网络不通,现将网络问题解决办法进行记录:本次实验OS为Centos7,网卡默认配置文件名为ifcfg-ens331.保留默认网卡网卡目录:/etc/sysconfig/network-scripts/保留默认......
  • CF113B Petr# 题解
    最近在做字符串的题,正好就给我随机了一道这个(题意给你一个字符串\(s\)以及一个开头串\(s_{begin}\)和结尾串\(s_{end}\),问该字符串中有多少个不同的子串,满足以\(s_{begin}\)开头,以\(s_{end}\)结尾。两个子串不同,当且仅当两个子串长度不同,或长度相同但至少有一个位置上......
  • 【P8819 [CSP-S 2022]】 星战 题解(图论 + 哈希)
    图论+哈希。Link.因为实在是太妙了所以写个题解。Solution因为每个点的出度都为\(1\),所以从任意一点出发永远可以走下去,故每次只需判断每个点度数是否为\(1\)即可。然后一三操作显然直接\(O(1)\)维护,\(50\pts\)。考虑二四操作。每次操作显然对点\(u\)的出度......