CF1148G

news/发布时间2024/5/21 2:08:15

冒个泡(?

rainbow_sjy 老师做法.

gcd > 1 无论是 fair 还是 antifair 都无法给出一个很好的限制, 这启发我们建立补图, 即化为 gcd = 1, 此时两种判定分别是: 选出大小为 \(k\) 的独立集选出大小为 \(k\) 且每个点所在联通块 \(\ge 2\).

考虑 \(2k\le n\) 的条件, 大概感觉一下是暗示我们, 在不满足第一个条件的情况下第二个条件必然满足, 那么我们找一个比较松的限制去判定, 所以以联通块为单位元来做.

第一个限制看起来比较困难, 我们先用一个比较松的条件: 如果联通块个数 \(\ge k\) 则有解, 构造显然, 判定也是简单的, 利用 mobius 反演每次加入一个数后看会不会和其他点连边即可.

尝试对于其它情况构造: 我们此时有 \(<k\) 个联通块,删除没有用的孤立点以后显然会剩下 \(p\ge \frac{n}{2}\ge k\) 个点, 我们从每个联通块选 \(\ge 2\) 个点即可.

于是我们现在需要知道每个联通块的具体情况, 我是不会这个的, sjy 老师给了一个高妙的解法, 直接整体二分, 大概就是先把上面那些独立集的点当作联通块的根, 对于点 \(x\), 若 \(x\) 和独立集 \([l,mid]\) 间的点有连边就向左递归, 反之向右递归, 于是得到了联通块的具体情况就可以直接做了. 时间复杂度 \(\mathcal O(n\log n2^{\omega(V)})\).

十分强大的题目和解法. 对于这类图上的构造, 积极地运用图上关系形式化描述判定条件方便思考, 对于其余题目, 描述二元组关系时也可以积极建图. 尽量将建图方式向提供便利限制地方向靠拢.

#include <bits/stdc++.h>
#define pb emplace_back
#define fir first
#define sec secondusing i64 = long long;
using pii = std::pair<int, int>;constexpr int maxn = 1e5 + 5, N = 1e7;
int prime[N + 5], cnt, mu[N + 5];
bool flag[N + 5];void init(int n) {mu[1] = 1;for(int i = 2;i <= n;++ i) {if(!flag[i]) prime[++ cnt] = i, mu[i] = -1;for(int j = 1;j <= cnt&&i * prime[j] <= n;++ j) {flag[i * prime[j]] = true;if(i % prime[j]) {mu[i * prime[j]] = -mu[i];} else {mu[i * prime[j]] = 0;break ;}}}return ;
}
int n, k, a[maxn], sum[N + 5], ord[maxn];
std::vector<int> d[maxn], det, ver, G[maxn];void add(int x, int st, int now) {if(st == d[x].size()) return sum[now] += mu[now], void();return add(x, st + 1, now), add(x, st + 1, now * d[x][st]);
}
void del(int x, int st, int now) {if(st == d[x].size()) return sum[now] = 0, void();return del(x, st + 1, now), del(x, st + 1, now * d[x][st]);
}
int qry(int x, int st, int now) {if(st == d[x].size()) return sum[now];return qry(x, st + 1, now) + qry(x, st + 1, now * d[x][st]);
}
void solve(int l, int r, std::vector<int> v) {if(l == r) {for(auto& x : v)G[l].pb(x);return ;}int mid = (l + r) >> 1;for(int i = l;i <= mid;++ i)add(det[i], 0, 1);std::vector<int> lqry, rqry;for(auto& x : v) {if(qry(x, 0, 1)) lqry.pb(x);else rqry.pb(x);}for(int i = l;i <= mid;++ i)del(det[i], 0, 1);return solve(l, mid, lqry), solve(mid + 1, r, rqry);
}int main() {scanf("%d %d", &n, &k); init(N);for(int i = 1;i <= n;++ i) {scanf("%d", &a[i]); int x = a[i];for(int j = 1;j <= cnt;++ j) {if(prime[j] * prime[j] > x) break ;if(x % prime[j]) continue ;while(x % prime[j] == 0) x /= prime[j];d[i].pb(prime[j]);}if(x > 1) d[i].pb(x);if(!qry(i, 0, 1)) add(i, 0, 1), det.pb(i);else ver.pb(i);}for(auto& x : det)del(x, 0, 1);int m = det.size() - 1; if(m + 1 >= k) {int t = 0;for(auto& x : det) {printf("%d ", x);++ t; if(t >= k) break ;}return 0;}solve(0, m, ver); std::iota(ord, ord + m, 0);std::sort(ord, ord + m, [&](const int& lhs, const int& rhs) {return G[lhs].size() > G[rhs].size();});int t = 0;for(int i = 0;i <= m;++ i) {t += G[ord[i]].size() + 1;if(t >= k) {std::vector<int> opt;for(int j = 0;j <= i;++ j)opt.pb(det[ord[j]]), opt.pb(G[ord[j]].back()), G[ord[j]].pop_back();for(int j = 0;j <= i;++ j)while(opt.size() < k&&!G[ord[j]].empty())opt.pb(G[ord[j]].back()), G[ord[j]].pop_back();for(auto& x : opt)printf("%d ", x);puts(""); return 0;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/70645701.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

电影推荐

《混凝土乌托邦》 --韩国

Begin of PHP

打开直接就是一份php代码,分析代码发现需要闯关,一共有五关 直接用ai给我翻译一下Level 1: 用户需要提供名为 key1 和 key2 的GET参数。 这两个参数的内容不应相同,但它们的MD5哈希值应该相同。 如果条件满足,将设置变量 $flag1 为True,否则会显示 "nope, this is le…

java面试点

语法基础 关键字:final: 用于表示某个变量、方法或类是最终的,不能被修改或继承 super: 可用于调用父类的方法或者字段 synchronized: 用于指定多线程代码中的同步方法、变量或者代码块 transient: 修饰的字段不会被序列化 const 在 C语言中是声明常量的关键字,在 Java …

软件测试:功能测试-接口测试-自动化测试-性能测试-验收测试

软件测试的主要流程一、测试主要的四个阶段 1.测试计划设计阶段:产品立项之后,进行需求分析,需求评审,业务需求评级,绘制业务流程图。确定测试负责人,开始制定测试计划; 2.测试准备阶段:各成员编写测试用例、先小组内评审、后会议评审,测试样机和配件,测试工具。 3.测…

学信息系统项目管理师第4版系列13_立项管理

立项管理1. 项目立项管理包括 1.1. 项目建议与立项申请 1.2. 项目可行性研究 1.2.1. 初步可行性研究 1.2.2. 详细可行性研究 1.2.2.1. 不可缺少 1.2.2.1.1. 【高21上选21】 1.2.3. 可以依据项目的规模和繁简程度合二为一 1.3. 项目评估与决策 2. 立项申请 2.1. 项目建议书 2.1.…

SOC芯片架构技术分析(三)

SOC芯片架构技术分析(三) 3.1 汽车:汽车平台未来需要高算力 1)汽车半导体涵盖了汽车芯片、功率器件、传感器等重要电子零部件。汽车的计算芯片包括传统的MCU芯片和SoC芯片。 MCU芯片一般包含CPU一个处理器单元;而汽车SoC一般包含多个处理单元。 2)ECU(Electronic Contro…