[Gym101138G][容斥原理]LCM-er

题意描述

给定\(n,a,b,x\)四个数字,需要计数满足如下条件序列的个数(答案对\(10^9+7\)取模),条件如下。

\[{a \le A_1 \le A_2 \le A_3 \le A_4 \le \cdots \le A_n \le b }\\
1 \le n\le 100,1\le a,b,x \le 10^9, a\le b \\
\]

以及需要满足 \(lcm(A_1,A_2,A_3,\cdots ,A_n)\)可以被\(x\)整除, 即

\[{lcm(A_1,A_2,A_3,\cdots ,A_n) | x}
\]

解法解析

根据正难则反的原则,我们可以考虑计数那些\(lcm\)不可以整除的序列。

仔细推断后发现,若将数\(x\)质因数分解为\(p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m}\)。

那么当且仅当将某序列的\(lcm\)质因数分解后,存在某个质数的幂小于\(x\)质因数分解后(若没有对应质数就将幂视为\(0\))对应质数的幂,此序列不合法。

\[\begin{aligned}
x &= p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m} \\
lcm &= p_1^{t_1}p_2^{t_2}\cdots p_m^{t_m} \\
\end{aligned}
\\
需要满足\ k_i \le t_i (1\le i\le m)
\]

注意到没有出现在\(x\)中的质数幂对答案无影响,所以我们只考虑\(x\)分解出来的质数幂。

现在我们枚举\(lcm​\)中不合法的位置,由于至少有一个位置不合法不好计算,我们利用容斥原理转而计算出单个位置不合法,两个位置不合法...m个位置不合法的方案数,即:

\(q_i代表第i个位置合法的情况, S代表所有位置的集合\{1,2,3,\cdots,m\},F代表满足指定情况下的方案数​\)

\[\begin{aligned}
F\left(\bigcap_{i=1}^m q_i \right) &= {All - F\left(\bigcup_{i=1}^m\overline{q_i} \right)} \\
F\left(\bigcup_{i=1}^m\overline{q_i} \right) &= {F(\overline{q_1})+F(\overline{q_2})+\cdots+F(\overline{q_m})} \\
&{-\sum_{1\le i\lt j\le m}F(\overline{q_i}\cap\overline{q_j})} \\
&{+\sum_{1\le i\lt j\lt k\le m}F(\overline{q_i}\cap\overline{q_j}\cap\overline{q_j})} \\
&\cdots \\
&{+\sum_{t\subseteq S}(-1)^{|t|}F\left( \bigcap_{i\in t}\overline{q_i}\ \right)}
\end{aligned}
\]

现在我们需要关注的就是对于一个位置集合,如何计算 \(F\left( \bigcap_{i\in t}\overline{q_i}\ \right)​\)。

容易发现若\(lcm\)在这些位置不满足,则构成序列的每一个数都不是选定位置质数幂的倍数,也就是所我们首先要筛选出\([a,b]​\)范围内有多少数字不是选定位置处质数幂的倍数即可。

联想在小于\(n\)的数中筛选不是\(2,3,5\)倍数的数字,我们再次利用容斥即可。

\[G(q_i)代表[a,b]区间内不为对应i位置质数幂倍数的数字数\\
{G\left( \bigcap_{i\in t}\overline{q_i}\ \right) =(b-a+1)+\sum_{j\subseteq t}(-1)^{|j|}\left( \Big\lfloor \frac{b}{\prod_{x\in j}p_x^{k_x}}\Big\rfloor - \Big\lfloor \frac{a-1}{\prod_{x\in j}p_x^{k_x}}\Big\rfloor \right)}
\]

将筛出的数字看作一个集合,大小为\(k\),现在可以从中任意选取\(n\)个数,每个数选取次数不限,求最后构成序列的有序方案数;即计算该多重集的\(n\)组合,可构成的方案数为\(\binom{n+k-1}{n}\)(挡板法)。

\[{F\left( \bigcap_{i\in t}\overline{q_i}\ \right) = \binom{G\left( \bigcap_{i\in t}\overline{q_i}\ \right)+n-1}{n}}
\]

整个过程需要两个容斥,做一次枚举子集即可,考虑到构成\(x​\)的质数幂不超过\(9\)个,复杂度\(O(n2^{\omega(n)}+3^{\omega(n)})\)。

PS:代码写得异常奇怪,就想试试不开数组只用vector

#include <bits/stdc++.h>
using namespace std; const int MOD = 1e9 + 7;
const int BIT = 11;
const int N = 105;
vector<int> inv(N, 1); void init_inverse() {
for (int i = 2; i < inv.size(); i++) {
inv[i] = 1LL * (MOD - MOD / i) * inv[MOD % i] % MOD;
}
} void resolve(int x, vector<int>& factors) {
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
factors.push_back(i);
x /= i;
while (x % i == 0) {
*factors.rbegin() *= i;
x /= i;
}
}
}
if (x > 1) factors.push_back(x);
} int calc(int x, int l, int r) {
return r / x - (l - 1) / x;
} int comb(int n, int m) {
if (m > n || m < 0) return 0;
int ret = 1;
for (int i = 1; i <= m; i++) {
ret = 1LL * ret * inv[i] % MOD;
ret = 1LL * ret * (n - i + 1) % MOD;
}
return ret;
} int main() {
init_inverse(); int n, a, b, x;
vector<int> factors; cin >> n >> a >> b >> x;
resolve(x, factors); vector<int> lcm(1 << factors.size(), 1);
vector<int> weight(1 << factors.size(), 0);
vector<int> cnt(1 << factors.size(), 0); for (int i = 0, j = 1; j < weight.size(); i++, j = j + j) {
weight[j] = i;
}
for (int i = 1; i < lcm.size(); i++) {
lcm[i] = lcm[i - (i & -i)] * factors[weight[i & -i]];
cnt[i] = cnt[i - (i & -i)] + 1;
} int ans = 0;
for (int i = 0; i < lcm.size(); i++) {
int temp = b - a + 1;
for (int j = i; j; j = i & (j - 1)) {
if (cnt[j] & 1) {
temp = (temp - calc(lcm[j], a, b) + MOD) % MOD;
} else {
temp = (temp + calc(lcm[j], a, b)) % MOD;
}
}
if (cnt[i] & 1) {
ans = (ans - comb(temp + n - 1, n) + MOD) % MOD;
} else {
ans = (ans + comb(temp + n - 1, n)) % MOD;
}
}
cout << ans << endl; return 0;
}

[Gym101138G][容斥原理]LCM-er的更多相关文章

  1. hdu 4497 GCD and LCM 质因素分解+排列组合or容斥原理

    //昨天把一个i写成1了 然后挂了一下午 首先进行质因数分解g=a1^b1+a2^b2...... l=a1^b1'+a2^b2'.......,然后判断两种不可行情况:1,g的分解式中有l的分解式中 ...

  2. HDU 4497 GCD and LCM(数论+容斥原理)

    GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...

  3. [洛谷P5106]dkw的lcm:欧拉函数+容斥原理+扩展欧拉定理

    分析 考虑使用欧拉函数的计算公式化简原式,因为有: \[lcm(i_1,i_2,...,i_k)=p_1^{q_{1\ max}} \times p_2^{q_{2\ max}} \times ... ...

  4. 【BZOJ-1853&2393】幸运数字&Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝

    1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 1817  Solved: 665[Submit][Status] ...

  5. HDU 1796 容斥原理

    How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  6. ZOJ 3233 Lucky Number --容斥原理

    这题被出题人给活活坑了,题目居然理解错了..哎,不想多说. 题意:给两组数,A组为幸运基数,B组为不幸运的基数,问在[low,high]区间内有多少个数:至少被A组中一个数整除,并且不被B中任意一个数 ...

  7. UVA 10325 The Lottery( 容斥原理)

    The Sports Association of Bangladesh is in great problem with their latest lottery `Jodi laiga Jai'. ...

  8. HDU1796 How many integers can you find(容斥原理)

    题目给一个数字集合,问有多少个小于n的正整数能被集合里至少一个元素整除. 当然是容斥原理来计数了,计算1个元素组合的有几个减去2个元素组合的LCM有几个加上3个元素组合的LCM有几个.注意是LCM. ...

  9. HDU 1796 How many integers can you find (状态压缩 + 容斥原理)

    题目链接 题意 : 给你N,然后再给M个数,让你找小于N的并且能够整除M里的任意一个数的数有多少,0不算. 思路 :用了容斥原理 : ans = sum{ 整除一个的数 } - sum{ 整除两个的数 ...

随机推荐

  1. POJ 3233 Matrix Power Series (矩阵分块,递推)

    矩阵乘法是可以分块的,而且幂的和也是具有线性的. 不难得到 Si = Si-1+A*Ai-1,Ai = A*Ai-1.然后矩阵快速幂就可以了. /*************************** ...

  2. 第九章 利用DOM脚本检索,替换,设置,追加样式信息

    我们浏览器里看到的网页是由以下三层信息构成的一个共同体: -结构层,由HTML或XHTML之类的标记语言负责去搭建文档的结构. -表示层,由CSS负责设置文档的呈现效果. -行为层,由JavaScri ...

  3. python查看安装包

    D:\Python27\Scripts>pip listbackports.ssl-match-hostname (3.4.0.2)basicauth (0.2)certifi (14.5.14 ...

  4. 制定RPM包和加入YUM源

    ##################################################### ##如有转载,请务必保留本文链接及版权信息 ##欢迎广大运维同仁一起交流linux/unix ...

  5. Ubuntu 下使用虚拟串口进行开发测试

    1. python 工具 #coding = utf-8 import pty import os import select def mkpty(): master1, slave = pty.op ...

  6. OpenFaceswap 入门教程(2):软件使用篇!

    安装完OpenFaceswap之后,是不是就迫不及待的想要“见证奇迹”了呢? 都说磨刀不误砍柴工.开始之前请先做一个准备.然后大致了解一下换脸的过程 换脸基本步骤是: 把视频切成很多图片 把图片中的人 ...

  7. JVM 内存分配和回收策略

    对象的内存分配,主要是在java堆上分配(有可能经过JIT编译后被拆为标量类型并间接地在栈上分配),如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配.少数情况下也是直接分配到老年代,分配规则不 ...

  8. Java Web 基础(一) 基于TCP的Socket网络编程

    一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...

  9. du 与df 统计系统磁盘不一致原因与解决方法

    事件起因: 同事发现云主机磁盘系统盘满了,准备清理系统盘,便利用du 命令统计了根目录下各文件夹的大小,发现统计的各文件夹的大小总和 加起来比 df 命令查看到的系统盘所使用空间 要小很多.这里记录下 ...

  10. (转)iOS静态库与动态库的区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...