「MtOI2018」魔力环
首先发现是经典的循环置换本质不同个数模型,根据 Burnside 引理:
\]
考虑第 \(i\) 个置换,整个置换分为了 \((n, i)\) 个大小为 \(\frac{n}{(n, i)}\) 的循环置换,不动点数量就是每个循环置换内颜色全部相等的方案。
那么只需要考虑每个循环置换的第一个位置,即 \(1 \sim (n, i)\) 这些位置填的方案,剩下的按周期补齐即可。
此时对于第一个周期,他的长度为 \((n, i)\) 需要放的黑球恰好为 \(\frac{m(n, i)}{n}(\frac{n}{(n, i)} \mid m)\),注意需要满足整除的条件。
如果 \(n \ne m\),那么问题的约数条件就等价于将第一个周期首位相接后满足题目两个要求,此时周期之间互补影响。
否则整个环都必须要被涂黑,只需简单判定即可,以下默认 \(n \ne m\)。
于是我们记 \(f(n, m)\) 为将长度为 \(n\) 的环用恰好 \(m\) 个黑珠子,不存在长度超过 \(k\) 的黑珠子连续段的方案。
考虑去掉环的限制,枚举首尾极长黑珠子长度之和 \(l\),有 \(l + 1\) 种方案分配给首尾段,然后钦定首段后放了一个白球,尾端前放了一个白球,就变成了一个序列问题。
同时注意为了方便我们将 \(m \le k\) 的情况判掉(答案即 \(\binom{n}{m}\)),这样可以省去很多讨论。
据此,我们令 \(g(n, m)\) 将长度为 \(n\) 的序列用恰好 \(m\) 个黑珠子,不存在长度超过 \(k\) 的黑珠子连续段的方案,则有 \(f\) 与 \(g\) 的关系:
\]
这本质上就是将 \(m\) 个黑珠子往 \(n - m\) 个白珠子里插的问题,考虑容斥,钦定有 \(i\) 段长度超过 \(k + 1\) 的黑珠子连续段,具体做法是将 \(k + 1\) 个黑珠子捆在一起插入到白珠子不同的 \(i\) 个缝隙中。由于黑珠子之间没有标号,那么忽略之前插入过的黑珠子,剩下的球随意插入到白珠子之间,那么有:
\]
同时根据前面的推导,可知计算一次 \(f(n, m)\) 的复杂度为 \(\mathcal{O}(m)\),根据一开始的 Burnside 引理,答案为:
\]
令 \(d = \frac{n}{(n, i)}\) 那么 \(\frac{n}{d} \mid n, d \mid m\),则可知 \(d\) 的取值集合至多只有 \(m\) 的所有约数,因此复杂度的一个上界是 \(\mathcal{O}(\sigma_1(m))\).
一个经典的估界是 \(\sigma_1(m) = \mathcal{O}(m \log \log m)\) 因此可以轻松通过。
一个变式:原问题去掉黑球个数限制,可以填任意个黑球的方案。
同样的思路,求出 \(f(n)\) 为长度为 \(n\) 的环用若干个黑球,不存在长度超过 \(k\) 的黑球连续段的方案。
首先还是判掉 \(n \le k\) 的情况,此时 \(f(n) = 2 ^ n\).
更进一步地,还是令 \(g(n)\) 为长度为 \(n\) 的序列用若干个黑球,首尾必须填白球,不存在长度超过 \(k\) 的黑球连续段的方案,还是有:
\]
对于 \(g\) 考虑 \(\rm dp\) 容斥转移,有初值 \(g(0) = g(1) = 1\),同时:
\]
那么最后一次填的是白球的方案就应该是 \(g(n - 1)\).
首先可以线性预处理出所有 \(0 \sim n\) 的 \(g\),然后直接按照上面哪个题的方法枚举约数计算,复杂度还是 \(\mathcal{O}(\sigma_1(n))\) 的。
当然也可以用上面的哪个方法再化简也可以得到这个复杂度,只不过细节有一点多
「MtOI2018」魔力环的更多相关文章
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
- 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance
提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...
随机推荐
- 编写Java程序,创建一个 Person 类,该类中有一个类成员变量 country、一个实例变量 name 和另一个实例变量 age。
返回本章节 返回作业目录 需求说明: 创建一个 Person 类,该类中有一个类成员变量 country.一个实例变量 name 和另一个实例变量 age. country 表示地区,name 表示姓 ...
- xpath如何使用正则、xpath定位svg标签、xpath常用集合
自己用到的xpath都收集下咯!!! 持续更新本页面 xpath查找svg图标 xpath('//*[local-name() = "svg" and @class="_ ...
- 对接网易云信音视频2.0呼叫组件集成到vue中,实现web端呼叫app,视频语音通话。
项目中需要实现视频通话功能,经过公司的赛选,采用网易云信的视频通话服务,app小伙伴集成很顺利.web端需要实现呼叫app端用户.网易云信文档介绍不全,vue的demo满足不了需求,和客服人员沟通,只 ...
- Java中List与数组互相转换
1.说明 在Java中,经常遇到需要List与数组互相转换的场景. List转换成数组,可以使用List的toArray()或者toArray(T[] a)方法. 数组转换成List,可以使用Arra ...
- Ranger-AdminServer安装Version2.0.0
Ranger-AdminServer安装, 对应的Ranger版本2.0.0. 1.安装规划 RangerAdmin安装依赖如下组件: mysql solr IP/机器名 安装软件 运行进程 dap2 ...
- xorm 条件查询时区的问题
问题描述:如果在查询的时候,直接传时间格式作为条件,时间会被驱动程序转为UTC格式,因此会有8个小时的误差. 解决方案1: 将查询时间转为字符串 db.where("time > ?& ...
- Centos7 安装LAMP以及nextcloud
第一步:安装apache 在centos中 apache叫httpd yum update #更新源 yum install httpd #安装apache systemctl stop firewa ...
- CentOS7端口被占用的解决办法
1.根据端口号得到其占用的进程的详细信息 netstat -tlnp|grep 80tcp 0 0 192.168.33.10:80 0.0.0.0:* ...
- 一文了解Flink State Backends
原文链接: 一文了解Flink State Backends 当我们使用Flink进行流式计算时,通常会产生各种形式的中间结果,我们称之为State.有状态产生,就必然涉及到状态的存储,那么Flink ...
- Solon 开发
Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...