当前位置: 首页 > news >正文

题解:AT_agc068_a [AGC068A] Circular Distance

牛牛题,看了很多次才看懂

题意:给出 \(L,n\),问在一个 \(L\) 长的环上,放置 \(n\) 个点,定义两点距离为两种路径中长度较短的长度,问所有放置方式的点的距离最大值之和。

做法:

首先先强制选定 \(0\) 号点,最后将答案乘上 \(\frac{L}{n}\) 即可,因为其可以作为 \(L\) 个点中的任何一个。

然后考虑如何计算答案。最大值等于 \(l\) 的比较难算,我们考虑差分一下,改成小于等于 \(l\) 的减去小于 \(l\) 的。

考虑怎么计算距离小于等于 \(l\) 的,因为我选了 \(0\),所以对于 \([1,l]\) 的和 \([L-l,L-1]\) 内的都可以选,\([l+1,L-l-1]\) 内都不可选。我记 \(len=L-2l-2\)。注意到这两个可选区间内的点都可以随便选,主要是两部分之间的限制相当麻烦。

我们称 \([1,l]\) 内的点为白点,\([L-l,L-1]\) 的点为黑点。手玩一下 \([L-l,L-1]\) 这些点会 ban 掉的区间,会发现,\(L-x\) 会 ban 掉 \([l+1-x,L-l-1-x]\) 也是一个长度为 \(len\) 的区间平移一下。我们把这些 ban 掉的区间只考虑对 \([1,l]\) 的影响,发现应该是若干个重叠的 \(len\) 长区间,最后的若干位置会叠出去,但是我们也只取 \([1,l]\) 的部分。

那么注意到我有一个黑色点的连续区间,那么映射在白色这边,就会是一段连续的黑色点区间,然后要求后面连续 \(len\) 个点被 ban 掉不能被选。

那么我们考虑有多少个除去到 \(l\) 的黑色连续段,记个数为 \(j\),为什么除去 \(l\) 因为最后一个连续段不必要禁掉一个长度为 \(len\) 的区间,有一个我们就至少需要禁掉 \(len\) 长的区间不能被选。我们考虑选出来哪些点,那么这样会有 \(l-len\times j\) 可以被选,从中任意选 \(n-1\) 个点作为黑白点选出来,方案数为 \(\binom{l-len\times j}{n-1}\)

然后我们考虑具体确定黑白点情况,那么我考虑把第一个点 \(0\) 当成白点放到最前,同时因为最后还有一个黑色连续段,加入最后有个黑点,所以总共有 \(n+1\) 个点。然后考虑我要分成多少个段,应该是 \(2j+2\) 个段,那么方案数就为 \(\binom{n}{2j+1}\)

乘起来就可以得到答案。注意 \(l=\frac{n}{2}\) 可以直接计算,答案为 \(\binom{L-1}{n-1}\)。直接计算即可。

复杂度瓶颈在于我需要枚举 \(len\) 的倍数,复杂度 \(O(L\log L)\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6 + 5, mod = 998244353;
int jc[maxn], revjc[maxn], n, m;
int C(int m, int n) {if(m < 0 || n < 0 || m < n)return 0;return jc[m] * revjc[n] % mod * revjc[m - n] % mod;
}
void prepare() {jc[0] = 1;for (int i = 1; i <= n; i++)jc[i] = jc[i - 1] * i % mod;revjc[0] = revjc[1] = 1;for (int i = 2; i <= n; i++)revjc[i] = (mod - mod / i) * revjc[mod % i] % mod;for (int i = 2; i <= n; i++)revjc[i] = revjc[i] * revjc[i - 1] % mod;
}
int d[maxn];
signed main() {cin >> n >> m;prepare();for (int i = 1; i < n / 2; i++) {int l = n - 2 * i - 2;int ans = 0;for (int j = 0; i - l * j >= m - 1 && 2 * j + 1 <= m; j++)ans = (ans + C(i - l * j, m - 1) * C(m, 2 * j + 1) % mod) % mod;d[i] = ans;}int ans = 0;d[n / 2] = C(n - 1, m - 1);for (int i = 1; i <= n / 2; i++) ans = (ans + (d[i] - d[i - 1] + mod) * i) % mod;cout << ans * n % mod * revjc[m] % mod * jc[m - 1] % mod << endl;return 0;
}
http://www.rkmt.cn/news/44747.html

相关文章:

  • 用 OKHttp 和 Retrofit 打造稳如磐石的网络请求:连接池与重试机制的实战指南 - 教程
  • 电脑监控软件,后台监控,千里眼监控
  • go sync.pool 学习笔记
  • 初识分布式训练
  • 电脑监控软件,后台监控,适合家庭电脑、员工电脑监控
  • 题解:P10856 【MX-X2-T5】「Cfz Round 4」Xor-Forces
  • 题解:AT_abc147_f [ABC147F] Sum Difference
  • 20231326《密码系统设计》第八周预习报告
  • 解放双手!使用Roslyn生成代码让你的 HTTP 客户端开发变得如此简单
  • 251109
  • electron-vite为linux打包成功,但是安装后运行无反应
  • 20231427田泽航第八周预习报告
  • PHP中各种超全局变量使用
  • 实用指南:TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 自动微分和梯度
  • 浏览器Blockstack.org全名字段输入限制缺失漏洞分析
  • 2025年维修厂家口碑排行榜:专业制冷服务首选
  • 行业内专业的维修厂家功能亮点
  • 疑似 CSP-SB、CSP-JB、NOSb 考题泄露
  • 如何禁止谷歌浏览器更新提示
  • 拓扑 AC 2025 线上 NOIP 联测 #2
  • 完整教程:FocusAny 发布v1.1.0 插件搜索过滤,FAD文件优化,插件显示MCP服务
  • 2025年11月合肥智能家居源头厂家排行
  • 深入解析:数据结构 04 栈和队列
  • 深入解析:软件编程课程:课程目录介绍 总纲
  • CCPC哈尔滨站-J. 幻想乡的裁判长
  • 牛客网测试题
  • OZI-Project代码注入漏洞分析与修复方案
  • 创建第一个pygame游戏窗口
  • P10194 [USACO24FEB] Milk Exchange G 做题记录
  • 点云配准基础知识