P10441 [JOISC 2024] 乒乓球 题解

news/2025/2/9 11:52:59/文章来源:https://www.cnblogs.com/Scarab/p/18705927

Description

构造一个点数为 \(n\) 的竞赛图,满足其中三元环的个数为 \(m\)

\(n\leq 5000\)

Solution

首先竞赛图的三元环个数是可以根据每个点的入度/出度求的。具体地,设 \(deg_i\) 表示 \(i\) 的出度,则三元环个数为 \(\binom{n}{3}-\sum{\binom{deg_i}{2}}\)

考虑怎么判断有无解。

注意到如果 \(deg_i+1<deg_j\),那么让 \(deg_i\leftarrow deg_i+1,deg_j\leftarrow deg_j-1\) 一定能让三元环数最多,所以度数越均匀,三元环数就越多。所以三元环最多的情况下 \(deg_i\) 一定等于 \(\lfloor\frac{n}{2}\rfloor\) 或者 \(\lceil\frac{n}{2}\rceil\),于是就能求出最多的三元环数了。

\(f_n\) 表示 \(n\) 个点的图三元环数量的最大值,结论是如果 \(m>f_n\) 则无解,否则有解。

构造就考虑先把初始度数设为数量最大时的情况,然后每次选择 \(deg_i=deg_j\),让 \(deg_i\leftarrow deg_i-1,deg_j\leftarrow deg_j+1\),会让三元环数减一。如果选不出来,就说明 \(deg=\{0,1,2,\ldots,n-1\}\),此时三元环数为 \(0\),不需要再调整了。

由于每次操作可以看成选两个度数相等的点,将它们之间的边取反,并且初始状态一定能构造,所以最终也可以构造出来。

现在得到了每个点的度数,构造竞赛图就考虑每次选择度数最小的点 \(i\),向其余任意 \(deg_i\) 个点连从 \(i\) 出发的边,剩下的 \(n-1-deg_i\) 个点就连到达 \(i\) 的边,然后把 \(i\) 删掉即可。

但是 \(m\) 可能到 \(O(n^3)\) 级别,暴力调整度数会超时。注意到 \(f(n)-f(n-1)\)\(O(n^2)\) 级别,所以只需要选择最小的 \(k\) 满足 \(f(k)\geq m\),然后构造大小为 \(k\) 三元环数为 \(m\) 的图,然后对剩余的点连出一个有向无环图即可。

时间复杂度:\(O(n^2\log n)\)

Code

#include <bits/stdc++.h>#define int int64_tconst int kMaxN = 5e3 + 5;int n, m;
bool g[kMaxN][kMaxN];int C(int n) { return 1ll * n * (n - 1) / 2; }int calc(int n) {if (n % 2 == 1) return 1ll * n * (n - 1) * (n - 2) / 6 - 1ll * n * C((n - 1) / 2);else {int k = (n - 1) / 2, cnt2 = C(n) - k * n, cnt1 = n - cnt2;return 1ll * n * (n - 1) * (n - 2) / 6 - (1ll * cnt1 * C(k) + 1ll * cnt2 * C(k + 1));}
}void construct(int n, int m) {static int cnt[kMaxN] = {0}, deg[kMaxN];std::fill_n(cnt, n - 1, 0);if (n % 2 == 1) {cnt[(n - 1) / 2] = n;} else {int k = (n - 1) / 2, cnt2 = C(n) - k * n, cnt1 = n - cnt2;cnt[k] = cnt1, cnt[k + 1] = cnt2;}std::priority_queue<int> q;for (int i = 1; i < n - 1; ++i)if (cnt[i] >= 2)q.emplace(i);for (int i = 1; i <= m; ++i) {int x = q.top(); q.pop();cnt[x] -= 2, ++cnt[x - 1], ++cnt[x + 1];if (cnt[x] >= 2) q.emplace(x);if (cnt[x - 1] == 2 && x - 1 >= 1) q.emplace(x - 1);if (cnt[x + 1] == 2 && x + 1 < n - 1) q.emplace(x + 1);}int c = 0;static int tmp[kMaxN];for (int i = 0; i < n; ++i) {for (int j = 1; j <= cnt[i]; ++j)deg[++c] = i, tmp[c] = i;}// std::cerr << n << ' ' << m << " : ";// for (int i = 1; i <= n; ++i) std::cerr << deg[i] << " \n"[i == n];for (int i = 1; i <= n; ++i) {std::vector<int> vec;assert(i + deg[i] <= n);// std::cerr << i << ' ' << deg[i] << '\n';for (int j = i + 1; j <= n; ++j) vec.emplace_back(j);std::sort(vec.begin(), vec.end(), [&] (int x, int y) { return deg[x] < deg[y]; });for (int j = 0; j < vec.size(); ++j) {int x = vec[j];if (j < deg[i]) g[i][x] = 1;else g[x][i] = 1, --deg[x];}}// for (int i = 1; i <= n; ++i) {//   assert(std::count(g[i] + 1, g[i] + 1 + n, 1) == tmp[i]);// }
}void dickdreamer() {std::cin >> n >> m;if (calc(n) < m) return void(std::cout << "No\n");for (int i = 1; i <= n; ++i)std::fill_n(g[i] + 1, n, 0);for (int k = 0; k <= n; ++k) {if (calc(k) >= m) {construct(k, calc(k) - m);for (int i = 1; i <= n; ++i)for (int j = std::max(i + 1, k + 1); j <= n; ++j)g[i][j] = 1;break;}}std::cout << "Yes\n";// int sum = 1ll * n * (n - 1) * (n - 2) / 6;// for (int i = 1; i <= n; ++i) sum -= C(std::count(g[i] + 1, g[i] + 1 + n, 1));// std::cerr << sum << '\n';// for (int i = 1; i <= n; ++i, std::cerr << '\n')//   for (int j = 1; j <= n; ++j)//     std::cerr << g[i][j];for (int i = 2; i <= n; ++i) {for (int j = 1; j < i; ++j)std::cout << g[i][j];std::cout << '\n';}
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;std::cin >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}

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

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

相关文章

htb Precious walkthrough

找到exp https://github.com/UNICORDev/exploit-CVE-2022-25765/blob/main/exploit-CVE-2022-25765.py 这个exp是有问题的 直接执行exp是没反应把他的payload cp出来手动粘贴到 框框里 然后就反弹shell成功flag在另一个用户里面 进过一番查找 在家目录的.bundle里的文件发现了…

Element简单组件开发

Element简单组件开发 1.项目创建 需要的环境:webStorm,NodeJS 创建一个工程化的Vue项目,在创建工程的文件夹中打开CMD命令窗口,执行命令:npm create vue@3.3.4 (3.3.4是我们安装Vue的版本)详细步骤说明: - Project name:------------------》项目名称,默认值:vue-proj…

⑨也能看懂的 nginx 与 C++ 简易版集成

原理概述 nginx 运行在端口A,转发数据给端口B,C++ 监听端口B的数据。 本文例子 使用 C++ 和 nginx 获取客户端的IP地址 代码 nginx 配置 #user nobody; worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/…

探秘Transformer系列之(1):注意力机制

探秘Transformer系列之(1):注意力机制 0x00 概述 因为各种事情,好久没有写博客了,之前写得一些草稿也没有时间整理(都没有时间登录博客和微信,导致最近才发现好多未读消息和私信,在这里和各位朋友说下万分抱歉)。现在恢复更新,是因为最近有些从非AI领域转过来的新同学…

Windows的MySQL数据库升级(解压包方式)

1、背景描述 原来的 MySQL 在安装时,是最新的稳定版本 5.7.33 。 经过一段时间后,在原来的 MySQL 版本中,发现存在漏洞。 因为 MySQL 的官方补丁,需要 Oracle 的 si 码(Support Identifier),不是免费的。 因此,只好将旧版本(5.7.33)升级到没有漏洞的新版本(5.7.44)…

【数据库架构】基于自主可控数据库实现两地三中心容灾的探索与实践

【摘要】金融行业作为第二批次信创试点单位,在大力推广国产软件的背景下,如何保障业务连续性、满足监管部门RPT及RTO指标是新形势下的重要技术挑战,本文作者结合所在单位案例实践,阐述基于OceanBase分布式数据库实现两地三中心容灾的解决方案,供同行参考。 【作者】陈明福…

小包搜题考试

安规考试懒人专用 一、在应用软件商店搜索小包搜题二、微信中找到题库,在微信中点击打开,点击右上角三个点,选择用其他应用打开三、选择小包搜题,进入之后会自动导入题库并给题库命名(随意起),导入成功之后退出小包搜题四、重新进入小包搜题,点击右上角的录屏搜题五、弹…

Qt监控设备离线检测/实时监测设备上下线/显示不同的状态图标/海康大华宇视华为监控系统

一、前言说明 监控系统中一般有很多设备,有些用户希望知道每个设备是否已经上线,最好有不同的状态图标提示,海康的做法是对设备节点的图标和颜色变暗处理,离线的话就变暗,有可能是加了透明度,而大华的处理是有个清晰的图标表示,上线图标右下角有个绿色指示灯,离线的右下…

VIP视频解析之小工具(免费自取)

我们通常会因为看电影但是需要vip却没有足够生活费去支持的困扰 我就在想有没有白嫖的方法呢(bushi 就在我苦恼的时候我发现了一个方法————就是被称为:解析 的技术这玩意就是最好的选择 但是可能部分人在刚刚接触的时候不会用的于是我就写了一个小软件来支持(只支持wind…

2025年值得推荐的 8 款 WPF UI 控件库

前言 今天大姚给大家分享 8 款开源、美观、功能强大、简单易用的WPF UI控件库,希望可以帮助到有需要的同学。 WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、数据绑定、样式和模板、动画效果等功能,让开发者可以…

github官网运行加速方法

github官网打不开的原因 访问github官网时是直接访问域名即github.com,中间有个域名通过DNS解析的过程,将域名解析为对应的ip地址,其实主要时间都是花在了DNS解析上,导致了github有时候能打开,有时候打不开,有时候访问很慢。 解决方案 1、Windows系统打开cmd,输入下列命…

关于AI生成艺术、自动驾驶汽车和Nutella片

Foto di Barbara Zandoval su Unsplash前言:当前时代人们似乎仍然坚信AI没有人类这样的创造力的!那人类的创造力又是什么呢?不也是从开始拥有认识能力,然后逐渐进化到现在空前的创造力的吗?如果AI也自我进化,创造力又能意味着什么? 我是个万事通。作为一名自由职业的在线…