传送门


先不考虑循环同构的限制,那么对于一个满足条件的序列,如果它的循环节长度为\(d\),那么与它同构的环在答案中就会贡献\(d\)次。

所以如果设\(f_i\)表示循环节长度恰好为\(i\)的满足条件的序列个数(不考虑循环同构),那么最后的答案就是\(\sum \frac{f_i}{i}\)。

所以问题变成了如何求\(f_i\)。注意到\(f_i\)直接求不是很好求,考虑计算\(cnt(\frac{n}{d} , \frac{m}{d})\)表示珠子数为\(\frac{n}{d}\)、黑色珠子数为\(\frac{m}{d}\)、不考虑循环同构的合法方案数,不难注意到\(\sum\limits_{i | d} f_i = cnt(\frac{n}{d} , \frac{m}{d})\)。所以只需要把所有\(cnt(\frac{n}{d} , \frac{m}{d})\)算出来然后莫比乌斯反演一下就可以得到所有\(f_i\)。

然后我们将原问题变成了不需要考虑循环同构的问题\(cnt(a,b)\)。

对于\(cnt(a,b)\),考虑\(a-b\)个白色球产生的\(a-b+1\)个区间,每一个区间内放入的黑色球的数量不能超过\(k\),且首尾放入的球的数量之和不能超过\(k\)。也就是要求\(\sum\limits_{i=0}^{a-b} x_i = b , \forall i , x_i \leq k , x_0 + x_{a-b} = k\)的满足条件的\(x\)序列的数量。不难得到这个序列的生成函数为\((\sum\limits_{i=0}^k x^i)^{a-b-1} (\sum\limits_{i=0}^k(i+1)x^i)\),我们要求的是它的\(x^b\)项系数。显然多项式快速幂不够优秀,考虑更快的方法。

由\(\sum\limits_{i=0}^k x_i = \frac{1 - x^{k+1}}{1 - x}\),可以得到

\((\sum\limits_{i=0}^k x^i)^{a - b - 1} = (1 - x^{k+1})^{a-b-1}(1 - x)^{-(a-b-1)}\)

\(\begin{align*}\sum\limits_{i=0}^k(i + 1)x^i &= \sum\limits_{i=0}^k \sum\limits_{j=i}^k x^i \\ &= \sum\limits_{i=0}^k\frac{x^i - x^{k+1}}{1 - x} \\ &= \frac{\sum\limits_{i=0}^k x^i - (k+1)x^{k+1}}{1-x} \\ &= \frac{\frac{1-x^{k+1}}{1-x} - (k+1)x^{k+1}}{1 - x} = \frac{1 - (k + 2)x^{k+1} + (k + 1)x^{k + 2}}{(1-x)^2} \end{align*}\)

所以生成函数可以变形为\((1 - x^{k+1})^{a-b-1}(1-x)^{-(a - b + 1)}(1 - (k + 2)x^{k+1} + (k+1)x^{k+2})\)

注意到最后的一部分多项式只有\(3\)项,意味着前面两项的卷积只有\(x^b,x^{b - k - 1} , x^{b-k-2}\)项会对\(x^b\)项系数产生贡献

而由二项式定理可知

\((1 - x^{k+1})^{a-b-1} = \sum\limits_{i=0}^{a-b-1} \binom{a-b-1}{i} (-1)^i x^{ki+i},(1 - x)^{-(a-b+1)} = \sum\limits_{i=0}^{+\infty} \binom{-(a-b+1)}{i}(-1)^i x^i = \sum\limits_{i=0}^{+\infty} \binom{a - b + i}{i}x^i\)

故设\(A = \sum\limits_{ki+i+j = b} \binom{a-b-1}{i} (-1)^i \binom{a-b+j}{j} , B = \sum\limits_{ki+i+j = b - k - 1} \binom{a-b-1}{i} (-1)^i \binom{a-b+j}{j} , C = \sum\limits_{ki+i+j = b - k - 2} \binom{a-b-1}{i} (-1)^i \binom{a-b+j}{j}\)

那么\(cnt(a,b) = A - (k + 2)B + (k+1)C\)。\(ABC\)的计算式子都可以通过枚举\(i\)做到\(\frac{b}{k+1}\)的复杂度,所以计算\(cnt(a,b)\)的总复杂度为\(\frac{\sigma(n)}{k + 1}\),其中\(\sigma(n)\)为\(n\)的约数和,近似\(n\ log\ logn\)。

#include<iostream>
#include<cstdio>
#include<cstring>
//This code is written by Itst
using namespace std; #define int long long
const int MAXN = 2e6 + 7 , MOD = 998244353;
int prm[MAXN] , jc[MAXN] , inv[MAXN] , mu[MAXN] , ans[MAXN];
int cnt , N , M , K;
bool nprm[MAXN]; inline int poww(int a , int b){
int times = 1;
while(b){
if(b & 1) times = times * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return times;
} void init(){
mu[1] = 1;
for(int i = 2 ; i <= 1e6 ; ++i){
if(!nprm[i]){
prm[++cnt] = i;
mu[i] = -1;
}
for(int j = 1 ; j <= cnt && prm[j] * i <= 1e6 ; ++j){
nprm[prm[j] * i] = 0;
if(i % prm[j] == 0) break;
mu[i * prm[j]] = -1 * mu[i];
}
}
jc[0] = 1;
for(int i = 1 ; i <= 2e6 ; ++i)
jc[i] = jc[i - 1] * i % MOD;
inv[2000000] = poww(jc[2000000] , MOD - 2);
for(int i = 1999999 ; i >= 0 ; --i)
inv[i] = inv[i + 1] * (i + 1) % MOD;
} int C(int b , int a){return b < a ? 0 : 1ll * jc[b] * inv[a] % MOD * inv[b - a] % MOD;} int calc(int A , int B){
int sum1 = 0 , sum2 = 0 , sum3 = 0;
for(int i = 0 ; (K + 1) * i <= B ; ++i){
int j = B - (K + 1) * i;
sum1 = (sum1 + (i & 1 ? -1 : 1) * C(A - B - 1 , i) * C(A - B + j , j) % MOD + MOD) % MOD;
}
for(int i = 0 ; (K + 1) * i <= B - K - 1 ; ++i){
int j = B - K - 1 - (K + 1) * i;
sum2 = (sum2 + (i & 1 ? -1 : 1) * C(A - B - 1 , i) * C(A - B + j , j) % MOD + MOD) % MOD;
}
for(int i = 0 ; (K + 1) * i <= B - K - 2 ; ++i){
int j = B - K - 2 - (K + 1) * i;
sum3 = (sum3 + (i & 1 ? -1 : 1) * C(A - B - 1 , i) * C(A - B + j , j) % MOD + MOD) % MOD;
}
return (sum1 - (K + 2) * sum2 % MOD + (K + 1) * sum3 + MOD) % MOD;
} signed main(){
#ifndef ONLINE_JUDGE
freopen("gift.in","r",stdin);
freopen("gift.out","w",stdout);
#endif
init();
ios::sync_with_stdio(0);
cin >> N >> M >> K;
if(M == 0){puts("1"); return 0;}
for(int i = 1 ; i <= M ; ++i)
ans[N / i] = M % i == 0 && N % i == 0 ? calc(N / i , M / i) : 0;
for(int i = 1 ; i <= N ; ++i)
if(N % i == 0 && M % (N / i) == 0)
for(int j = 2 ; j * i <= N ; ++j)
ans[i * j] = (ans[i * j] + ans[i] * mu[j] + MOD) % MOD;
int sum = 0;
for(int i = 1 ; i <= N ; ++i)
if(N % i == 0 && M % (N / i) == 0)
sum = (sum + poww(i , MOD - 2) * ans[i]) % MOD;
cout << sum << '\n';
return 0;
}

Luogu4916 魔力环 莫比乌斯反演、组合、生成函数的更多相关文章

  1. 【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数

    [题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体 ...

  2. LOJ6519. 魔力环(莫比乌斯反演+生成函数)

    题目链接 https://loj.ac/problem/6519 题解 这里给出的解法基于莫比乌斯反演.可以用群论计数的相关方法代替莫比乌斯反演,但两种方法的核心部分是一样的. 环计数的常见套路就是将 ...

  3. [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)

    题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...

  4. bzoj 2440 简单莫比乌斯反演

    题目大意: 找第k个非平方数,平方数定义为一个数存在一个因子可以用某个数的平方来表示 这里首先需要考虑到二分才可以接下来做 二分去查找[1 , x]区间内非平方数的个数,后面就是简单的莫比乌斯反演了 ...

  5. hdu 1695 GCD 莫比乌斯反演入门

    GCD 题意:输入5个数a,b,c,d,k;(a = c = 1, 0 < b,d,k <= 100000);问有多少对a <= p <= b, c <= q <= ...

  6. 洛谷P3307 [SDOI2013]项链 [polya定理,莫比乌斯反演]

    传送门 思路 很明显的一个思路:先搞出有多少种珠子,再求有多少种项链. 珠子 考虑这个式子: \[ S3=\sum_{i=1}^a \sum_{j=1}^a\sum_{k=1}^a [\gcd(i,j ...

  7. Coprime (单色三角形+莫比乌斯反演(数论容斥))

    这道题,先说一下单色三角形吧,推荐一篇noip的论文<国家集训队2003论文集许智磊> 链接:https://wenku.baidu.com/view/e87725c52cc58bd631 ...

  8. HDU 5321 Beautiful Set (莫比乌斯反演 + 逆元 + 组合数学)

    题意:给定一个 n 个数的集合,然后让你求两个值, 1.是将这个集合的数进行全排列后的每个区间的gcd之和. 2.是求这个集合的所有的子集的gcd乘以子集大小的和. 析:对于先求出len,len[i] ...

  9. BZOJ 3309 莫比乌斯反演

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3309 题意:定义f(n)为n所含质因子的最大幂指数,求 $Ans=\sum _{i=1} ...

随机推荐

  1. Android为TV端助力 最简单的自定义圆点view

    首先创建一个选择器,用来判断圆点状态,可以根本自己的需求改 <selector xmlns:android="http://schemas.android.com/apk/res/an ...

  2. 配置 Sublime Text 3 作为Python R LaTeX Markdown IDE

    配置 Sublime Text 3 作为Python R LaTeX Markdown IDE 配置 Sublime Text 3 作为Python IDE IDE的基本功能:代码提醒.补全:编译文件 ...

  3. (后端)安装mongodb以及设置为windows服务 详细步骤(转)

    1.在data文件夹下新建一个log文件夹,用于存放日志文件,在log文件夹下新建文件mongodb.log 2.在 D:\mongodb文件夹下新建文件mongo.config,并用记事本打开mon ...

  4. Javascript数组系列四之数组的转换与排序Sort方法

    今天我们继续来介绍 Javascirpt 数组中的方法,也是数组系列的第四篇文章,因为数组的方法众多,每篇文章我们都对数组的每个方法都有比较细致的描述,只要你能够从中成长一点点,那我们的目的就达到了, ...

  5. Sql Server XML

    实验数据: Create table xmldata (name NVARCHAR(20), age int, sex NVARCHAR(5) ) INSERT INTO xmldata VALUES ...

  6. NSJSONSerialization 反序列化失败 NSCocoaErrorDomain Code=3840

    NSJSONSerialization 反序列化失败 NSCocoaErrorDomain Code=3840  NSCocoaErrorDomain Code=3840 “No string key ...

  7. JavaScript -- 时光流逝(十):Screen 对象、History 对象、Location 对象

    JavaScript -- 知识点回顾篇(十):Screen 对象.History 对象.Location 对象 1. Screen 对象 1.1 Screen 对象的属性 (1) availHeig ...

  8. March 11th, 2018 Week 11th Sunday

    All good things must come to an end. 好景无常. Love is when the other person's happiness is more importa ...

  9. 异常--finally关键字

    finally定义: finally{}代码块中的代码是一定会执行的,一般用来关闭资源或者一些必须执行的代码,如数据库连接的关闭

  10. Go学习笔记08-包

    Go学习笔记08-包 Go语言 封装 包 封装 CamelCase命名规则 首字母大写:public 首字母小写:private 包 一个目录即一个包 main包为可执行入口,只能有一个main包 为 ...