首页 > 其他分享 >Atcoder AGC062C Mex of Subset Sum

Atcoder AGC062C Mex of Subset Sum

时间:2023-07-14 20:55:50浏览次数:41  
标签:Subset Atcoder insert int Sum 对于 个数 long 操作

对 \(a_i\) 从小到大进行排序,因为想到若 \(< a_{i - 1}\) 的不能取到的数因为 \(a_i > a_{i - 1}\) 肯定是能保证取不到的。
对排完序的 \(a_i\) 做一个前缀和 \(s_i = \sum\limits_{j = 1}^n\),令 \(A_i\) 为 \(a_{1\sim i}\) 中无法表示为子序列之和且 \(< s_i\) 的正整数的集合。

考虑现在已经处理完 \(i - 1\) 位,对于第 \(i\) 位 \(A_i\) 相对 \(A_{i - 1}\) 有什么变化。
考虑讨论 \(s_{i - 1}\) 与 \(a_i\) 的大小关系。

  1. \(s_{i - 1}\le a_i\):

    • 对于 \(x\in A_{i - 1}\) 的 \(x\),因为 \(a_{i} > s_{i - 1} > x\),所以 \(a_i\) 的存在对 \(x\) 并没有影响。
    • 对于 \(x\in (s_{i - 1}, a_i)\) 的 \(x\),选 \(a_i\) 就会比 \(x\) 大,不选就会比 \(x\) 小,所以能加入 \(A_i\)。
    • 对于 \(x - a_i\in A_{i - 1}\) 的 \(x\),肯定 \(x > a_i\),不选 \(a_i\) 则肯定凑不出来,选了在 \(A_{i - 1}\) 中也凑不出来。

    能发现对于第 \(1,2\) 类的 \(x\) 后面的操作肯定不会排除掉,所以若第 \(1,2\) 类的 \(x\) 的数量已经 \(\ge k\) 可以直接输出;但对于第 \(3\) 类的 \(x\) 后面的操作可能会排除一部分,其对答案的贡献是不确定的,不能直接输出。

    时间复杂度分析:
    考虑第 \(1, 2\) 类操作因为个数 \(\ge k\) 就直接输出,所以个数一定 \(< k\),第 \(3\) 类操作个数上限就为 \(|A_{i - 1}|\),所以有 \(|A_i| < |A_{i - 1}| + k\),即每次操作 \(A_i\) 内最多增加 \(k\) 个数。

  2. \(s_{i - 1} > a_i\):

    • 对于 \(x\in A_{i - 1}\cap [1, a_i)\) 的 \(x\),因为 \(a_i > x\),所以 \(a_i\) 的存在对 \(x\) 并无影响。
    • 对于 \(x\in A_{i - 1}\cap (a_i, s_{i - 1})\) 且 \(x - a_i \in A_{i - 1}\) 的 \(x\),选不选 \(a_i\) 都凑不出来。
    • 对于 \(x\in (s_i, \infty)\) 且 \(x - a_i\in A_{i - 1}\) 的 \(x\),不选 \(a_i\) 肯定小,选了 \(a_i\) 也凑不出来。

    能发现对于第 \(1\) 类的 \(x\) 后面的操作肯定不会排除掉,所以若第 \(1\) 类操作的 \(x\) 的数量已经 \(\ge k\) 可以直接输出;但对于第 \(2,3\) 类的 \(x\) 后面的操作可能会排除一部分,其对答案的贡献是不确定的,不能直接输出。

    时间复杂度分析:
    考虑第 \(1\) 类操作因为个数 \(\ge k\) 就直接输出,所以个数一定 \(< k\),第 \(2, 3\) 类操作个数上限就为 \(|A_{i - 1}|\),所以有 \(|A_i| < |A_{i - 1}| + k\),即每次操作 \(A_i\) 内最多增加 \(k\) 个数。

若跑完后 \(|A_n| < k\),直接从 \(s_n + 1\) 开始往后选数直到 \(|A_n| = k\)。

考虑用 set 来维护集合,时间复杂度为 \(O(n^2k\log_2 (nk))\)。

// lhzawa(https://www.cnblogs.com/lhzawa/)
// Problem: C - Mex of Subset Sum
// Contest: AtCoder - AtCoder Grand Contest 062
// URL: https://atcoder.jp/contests/agc062/tasks/agc062_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int N = 60 + 5;
long long a[N];
int main() {
	int n, k;
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &a[i]);
	}
	function<void (const set<long long>&)> print = [&k](const set<long long> zxx) -> void {
		for (set<long long>::iterator i = zxx.begin(); k; i++, k--) {
			printf("%lld ", (*i));
		}
		return ;
	};
	sort(a + 1, a + n + 1);
	long long s = 0;
	set<long long> A, B;
	for (int i = 1; i <= n; i++) {
		if (s <= a[i]) {
			B = A;
			for (long long j = s + 1; j < a[i]; j++) {
				A.insert(j);
				if (A.size() >= k) {
					print(A);
					return 0;
				}
			}
			for (long long j : B) {
				A.insert(j + a[i]);
			}
		}
		else {
			B.clear();
			for (long long j : A) {
				if (j < a[i]) {
					B.insert(j);
				}
				if (B.size() >= k) {
					print(B);
					return 0;
				}
			}
			for (long long j : A) {
				if (a[i] < j && A.count(j - a[i])) {
					B.insert(j);
				}
				if (j + a[i] > s) {
					B.insert(j + a[i]);
				}
			}
			A = B;
		}
		s += a[i];
	} 
	for (s++; A.size() < k; A.insert(s), s++);
	print(A);
	return 0;
}

标签:Subset,Atcoder,insert,int,Sum,对于,个数,long,操作
From: https://www.cnblogs.com/lhzawa/p/17554961.html

相关文章

  • SMU Summer 2023 Contest Round 3
    SMUSummer2023ContestRound3A-CurriculumVitae思路:要求0后不能有1,当某个数都不删时,值为前面所有的0的个数加后面所有1的个数,求出最大即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>PII;typedefpair<string,int>......
  • SMU Summer 2023 Contest Round 2
    SMUSummer2023ContestRound2A-TreasureHunt思路:判断Δx和Δy能否分别整除x和y,求出需要的步数,两者的步数须同奇或同偶#include<bits/stdc++.h>usingnamespacestd;//#defineintlonglongtypedefpair<int,int>PII;typedefpair<string,int>PSI;type......
  • SMU Summer 2023 Contest Round 1
    SMUSummer2023ContestRound1A-TheContest思路:求出最短解决问题总时间,在所有区间找出大于等于总时间的最短时刻。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>PII;typedefpair<string,int>PSI;typedefpair<strin......
  • SMU Summer 2023 Contest Round 3
    A.CurriculumVitae题意:给出一串01序列,可以删除任意个元素,使得1后面没有0思路:枚举01分界点,使得统计前面0的个数和后面1的个数,取最大值。点击查看代码#include<bits/stdc++.h>usingnamespacestd;inta[110];intmain(){ios::sync_with_stdio(0),cin.tie(0),co......
  • AtCoder Beginner Contest 294
    A-Filter#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongint32_tmain(){ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);intn;cin>>n;for(intx;n;n--){cin>&......
  • AtCoder Beginner Contest 309 - D(最短路)
    目录D-AddOneEdge法一:dijkstra法二:BFS+队列题目传送门:abc309前面的简单题就不放了D-AddOneEdge题意:给你一个无向图图,分为两个连通块,一个顶点数为n1(1~n1),一个顶点数为n2(n1+1~n1+n2),图中共有m条边。如果现在在两个连通块之间连接一条边,那么顶点1与顶点n1+n2......
  • SMU Summer 2023 Contest Round 1
    A.TheContest题意:要做n道题,每道题花费时间a[i],但是只有几个时间段可以提交,问最早什么时间可以完成。思路:直接计算做完全部的题目所花费的时间,然后找到可以提交的时间段,和左端取最大值,就能得出结果。点击查看代码#include<bits/stdc++.h>usingnamespacestd;constint......
  • AtCoder Beginner Contest 162
    AtCoderBeginnerContest162ABCD全暴力E数学题看不懂,感性理解F线性dp,非常基础我不会,寄E-SumofgcdofTuples(Hard)看了题解发现好多做法都是推一堆式子,我实在看不懂(卷积莫反啥啥的呜呜呜)然后看见这个感觉比较好感性理解:(来自洛谷题解)#include<bits/stdc++.h>#def......
  • Atcoder Regular Contest 114 F - Permutation Division
    显然分成\(k\)段以后,最大化形成的排列的字典序的策略是将所有段按第一个元素的大小降序排列。由于最终排列的字典序肯定\(\ge\)原排列的字典序,因此我们考虑最大化最终排列与原排列的LCP,这部分就考虑二分答案,记\(dp_i\)表示以\(p_1\)开始\(p_i\)结尾的LDS的长度,那么......
  • AtCoder Regular Contest 164 A~C
    A题都没做出来(被自已菜晕A.TernaryDecompositionA-TernaryDecomposition(atcoder.jp)题意给定一个正整数\(N\),问是否存在\(K\)个整数,使得\(N=3^{m_1}+3^{m_2}+...+3^{m_k}\)思路首先对于一个正整数\(N\),最多有\(N\)个整数使得正式成立,即\(m_i\)全为0。再对\(N\)进行三......