首页 > 其他分享 >AtCoder Regular Contest 139 C One Three Nine

AtCoder Regular Contest 139 C One Three Nine

时间:2023-05-23 15:34:25浏览次数:59  
标签:AtCoder typedef Contest ll Three long lld

洛谷传送门

AtCoder 传送门

闲话:做这场的 B 用时跟 C 差不多

不会直接构造,因此这是一个无脑做法。

考虑对于 \(\forall x \in [1, n], y \in [1, m], (x + 3y, 3x + y)\) 看成一个点,那么选择的 \((x, y)\) 要满足,不存在一行或一列有超过 \(1\) 个点。

这启发我们对于合法的点 \((a, b)\),行和列连边,即 \(a \to b\),那么就是要构造出这个二分图的一个最大匹配。

考察合法的连边,\(a, b\) 应满足什么条件。不难推出:

  • \(8 \mid (3a - b)\);
  • \(\max(3a - 8m, \frac{a + 8}{3}) \le b \le \min(3a - 8, \frac{8n + a}{3})\)。

所以如果知道了 \(a\),那么 \(a\) 连出去的 \(b\) 模 \(8\) 都相等,并且在所有模 \(8\) 与它相等的数中是一段区间。

因为 \(a\) 有 \(O(n + m)\) 个,所以直接枚举 \(a\),贪心取出最小的满足要求的 \(b\),即可构造。实现时可以开 \(8\) 个 set

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

code
// Problem: C - One Three Nine
// Contest: AtCoder - AtCoder Regular Contest 139
// URL: https://atcoder.jp/contests/arc139/tasks/arc139_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

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

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

const int maxn = 1000100;

ll n, m;
set<ll> S[8];

void solve() {
	scanf("%lld%lld", &n, &m);
	for (ll y = 4; y <= n * 3 + m; ++y) {
		S[y % 8].insert(y);
	}
	for (int i = 0; i < 8; ++i) {
		S[i].insert(-1e9);
		S[i].insert(1e9);
	}
	vector<pii> vc;
	for (ll a = 4; a <= n + m * 3; ++a) {
		ll l = max(3 * a - m * 8, (a + 10) / 3), r = min(3 * a - 8, (8 * n + a) / 3);
		if (l > r) {
			continue;
		}
		ll b = *S[3 * a % 8].lower_bound(l);
		if (b > r) {
			continue;
		}
		// printf("%lld %lld\n", a, b);
		ll x = (3 * b - a) / 8, y = (3 * a - b) / 8;
		vc.pb(x, y);
		S[3 * a % 8].erase(b);
	}
	printf("%d\n", (int)vc.size());
	for (pii p : vc) {
		printf("%lld %lld\n", p.fst, p.scd);
	}
}

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

标签:AtCoder,typedef,Contest,ll,Three,long,lld
From: https://www.cnblogs.com/zltzlt-blog/p/17425373.html

相关文章

  • Atcoder 选做
    [ARC103F]DistanceSums(构造,重心)首先显然\(D_i\)的最小值被重心取到,不妨以重心为根。对于一条边连接的两个点\(x,y\),不妨设这条边\(x\)侧的点数为\(siz_x\),\(y\)侧为\(siz_y\)。那么\(D_y=D_x+siz_x-siz_y=D_x+siz_x-(n-siz_x)=D_x+2\timessiz_x-n\)。那么......
  • Atcoder Grand Contest 060 D - Same Descent Set
    先推式子。设\(f(S)\)表示decent集合恰好为\(S\)的排列个数,\(g(S)\)表示\(S\)是\(p\)的decent集合的一个子集的排列\(p\)个数,\(g'(\{a_1,a_2,\cdots,a_k\})=\dfrac{n!}{a_1!(a_2-a_1)!(a_3-a_2)!\cdots(a_k-a_{k-1})!(n-a_k)!}\),那么有:\[\begin{aligned}ans=&\......
  • Atcoder Beginner Contest ABC302 题解
    代码见此:https://atcoder.jp/contests/abc302/submissions?f.Task=&f.LanguageName=&f.Status=&f.User=frequenter。AAttackhttps://atcoder.jp/contests/abc302/tasks/abc302_a直接计算a/b,有余数的话答案加一。BFindSnukehttps://atcoder.jp/contests/abc302/tasks/abc......
  • AtCoder Regular Contest 132 D Between Two Binary Strings
    洛谷传送门AtCoder传送门提供一个dp思路。下文设串长为\(n\),串中\(1\)个数为\(m\)。考虑如何求\(d(s,t)\)。设\(s\)的\(1\)位置分别为\(a_1,a_2,...,a_m\),\(t\)的\(1\)位置分别为\(b_1,b_2,...,b_m\)。那么\(d(s,t)=\sum\limits_{i=1}^m|a_i-b......
  • 2023 Xian Jiaotong University Programming Contest
    A.大水题#include<bits/stdc++.h>#include<ext/rope>#include<ext/pb_ds/assoc_container.hpp>usingnamespacestd;usingnamespace__gnu_cxx;usingnamespace__gnu_pbds;#definefifirst#definesesecond#definelcu<<1#define......
  • AtCoder Beginner Contest 302 Ex Ball Collector
    洛谷传送门AtCoder传送门考虑如果只询问一次怎么做。连边\((a_i,b_i)\),对于每个连通块分别考虑。这是ARC111B,如果一个连通块是树,肯定有一个点不能被选;否则有环,一定能构造一种方案,使得每个点都被选。那么现在对于每个点都要求,考虑dfs时合并当前的\((a_u,b_u)\),并且使用......
  • 【题解】Atcoder ABC302 F,G,Ex
    完全不会G和Ex,这些套路还是要积累一下的。F.MergeSet题目描述:给定\(n\)个集合,每次可以合并两个有交的集合,问最少多少次合并可以让\(1\)和\(m\)位于同一个集合中。题目分析:一开始将题读成了将\([1,m]\)位于同一个集合中,然后就感觉这个题相当不可做。因为集合的元......
  • AtCoder Regular Contest 130 E Increasing Minimum
    这题太神仙了吧!感觉还不是很懂,但是尽力理一下思路。设\(t_x\)为最大的\(j\)使得\(i_j=x\),不存在则\(t_x=0\)。设\(1\simn\)的数按照\(t\)从小到大排序后是\(p_1,p_2,...,p_n\),设\(q_i\)为\(i\)在\(p\)中的排名,即\(q_{p_i}=i\)。发现正着不好考虑,......
  • AtCoder Beginner Contest 302
    A-Attack(abc302a)题目大意给定怪物的血量\(a\)和你每次攻击扣除的血量\(b\),问打多少次怪物才会死。解题思路答案即为\(\lceil\frac{a}{b}\rceil=\lfloor\frac{a+b-1}{b}\rfloor\)神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=long......
  • AtCoder Regular Contest 130 C Digit Sum Minimization
    洛谷传送门AtCoder传送门分类讨论,但是写起来挺答辩的。首先发现我们要使进位尽量多。特判怎么重排都没有进位的情况(\(a_i+b_i<10\))。然后枚举个位选的两个数字,并且要求它们和\(\ge10\)。如果当前位两个位都有数字,那么从小到大枚举数位的和\(\in[9,18]\);如果有数字......