ACM学习历程—HDU4675 GCD of Sequence(莫比乌斯)
Description
Alice is playing a game with Bob.
Alice shows N integers a 1, a 2, …, a N, and M, K. She says each integers 1 ≤ a i ≤ M.
And now Alice wants to ask for each d = 1 to M, how many different sequences b 1, b 2, …, b N. which satisfies :
1. For each i = 1…N, 1 ≤ b[i] ≤ M
2. gcd(b 1, b 2, …, b N) = d
3. There will be exactly K position i that ai != bi (1 ≤ i ≤ n)
Alice thinks that the answer will be too large. In order not to annoy Bob, she only wants to know the answer modulo 1000000007.Bob can not solve the problem. Now he asks you for HELP!
Notes: gcd(x 1, x 2, …, x n) is the greatest common divisor of x 1, x 2, …, x n
Input
The input contains several test cases, terminated by EOF.
The first line of each test contains three integers N, M, K. (1 ≤ N, M ≤ 300000, 1 ≤ K ≤ N)
The second line contains N integers: a 1, a 2, ..., a n (1 ≤ a i ≤ M) which is original sequence.
Output
For each test contains 1 lines :
The line contains M integer, the i-th integer is the answer shows above when d is the i-th number.
Sample Input
3 3 33 3 33 5 31 2 3
Sample Output
7 1 059 3 0 1 1
Hint
In the first test case : when d = 1, {b} can be : (1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 2, 2) (2, 1, 1) (2, 1, 2) (2, 2, 1) when d = 2, {b} can be : (2, 2, 2) And because {b} must have exactly K number(s) different from {a}, so {b} can't be (3, 3, 3), so Answer = 0
题目关键在于找出什么东西是可以求的。
之前做过莫比乌斯的题目,一般都是d | gcd的比较好求。
那么考虑对于d | gcd的情况F(d)有多少种?
如果当前数列里面有num[d]个数是d的倍数。
首先由于要改掉k个,那么有n-k个数是不变的,如果这些数有不是d的倍数,那么不满足条件了。
即如果n-k > num[d],F(d) == 0。
于是对于余下的n-k,可以从num[d]个数中选取,即C(num[d], n-k)。
然后对于被改掉了k个数来说,里面肯定有num[d]-(n-k)个数是d的倍数,则有quickPow(m/d-1,num[d]-(n-k))种选法。最后剩余的n-num[i]个数,则有quickPow(m/i, n-num[i])种选法。最后乘起来就是结果了。需要对于0的情况考虑一下。
于是F(d)有了,而F(d) = sum(f(n)) (d|n)。
这一步网上有把F(d)一道一边,f(d)一到另一边计算的。这里采用莫比乌斯反演。
然后C组合数的求法的话,预处理出所有排列数p[]和逆元invp[],这里的invp是用前一个invp[i-1]乘上i的逆元计算的,i的逆元又是用O(n)算法先处理出来的。总的复杂度是O(n)。
快速幂复杂度是logn。
然后莫比乌斯的复杂度是nlogn。
最后总的复杂度是nlogn的。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long
#define MOD 1000000007 using namespace std; const int maxN = ;
int n, m, k;
int num[maxN];
int sum[maxN];
int p[maxN], inv[maxN], invp[maxN];
int u[maxN], prime[maxN];
bool vis[maxN];
int ans[maxN]; //莫比乌斯反演
//F(n)和f(n)是定义在非负整数集合上的两个函数
//并且满足条件F(n) = sum(f(d)) (d|n)
//那么f(n) = sum(u(d)*F(n/d)) (d|n)
//case 1: if d = 1, u(d) = 1
//case 2: if d = p1*p2...pk, (pi均为互异素数), u(d) = (-1)^k
//case 3: else, u(d) = 0;
//性质1: sum(u(d)) (d|n) = 1 (n == 1) or 0 (n > 1)
//性质2: sum(u(d)/d) (d|n) = phi(n)/n
//另一种形式:F(d) = sum(f(n)) (d|n) => f(d) = sum(u(n/d)*F(n)) (d|n)
//线性筛选求莫比乌斯反演函数代码
void mobius()
{
memset(vis, false,sizeof(vis));
u[] = ;
int cnt = ;
for(int i = ; i < maxN; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
u[i] = -;
}
for(int j = ; j < cnt && i*prime[j] < maxN; j++)
{
vis[i*prime[j]] = true;
if(i%prime[j])
u[i*prime[j]] = -u[i];
else
{
u[i*prime[j]] = ;
break;
}
}
}
} void init()
{
mobius();
//***预处理所有i在质数MOD下的逆元
inv[] = ;
for (int i = ; i < maxN; i++)
inv[i] = (LL)inv[MOD%i]*(MOD-MOD/i) % MOD;
p[] = ;
invp[] = inv[];
for (int i = ; i < maxN; ++i)
{
p[i] = (LL)p[i-]*i%MOD;
invp[i] = (LL)invp[i-]*inv[i]%MOD;
}
} void input()
{
memset(num, , sizeof(num));
int tmp;
for (int i = ; i < n; ++i)
{
scanf("%d", &tmp);
num[tmp]++;
} for (int i = ; i <= m; ++i)
{
for (int j = i*; j <= m; j += i)
num[i] += num[j];
}
} inline int C(int x, int y)
{
int ans;
ans = (LL)p[x]*invp[x-y]%MOD;
ans = (LL)ans*invp[y]%MOD;
return ans;
} //快速幂m^n
LL quickPow(LL x, int n)
{
if (n == )
return ;
if (x == )
return ;
LL a = ;
while (n)
{
a *= n& ? x : ;
a %= MOD;
n >>= ;
x *= x;
x %= MOD;
}
return a;
} void work()
{
memset(sum, , sizeof(sum));
memset(ans, , sizeof(ans));
for (int i = ; i <= m; ++i)
{ if (num[i] < n-k)
sum[i] = ;
else
{
sum[i] = C(num[i], n-k)*quickPow(m/i, n-num[i])%MOD;
sum[i] = quickPow(m/i-, num[i]-(n-k))*sum[i]%MOD;
}
}
for (int i = ; i <= m; ++i)
{
for (int j = i; j <= m; j += i)
{
ans[i] += (LL)u[j/i]*sum[j]%MOD;
ans[i] = (ans[i]%MOD+MOD)%MOD;
}
}
for (int i = ; i <= m; ++i)
{
if (i != )
printf(" ");
printf("%d", ans[i]);
}
printf("\n");
} int main()
{
//freopen("test.in", "r", stdin);
init();
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
input();
work();
}
return ;
}
ACM学习历程—HDU4675 GCD of Sequence(莫比乌斯)的更多相关文章
- ACM学习历程—HDU1695 GCD(容斥原理 || 莫比乌斯)
Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = ...
- hdu4675 GCD of Sequence 莫比乌斯+组合数学
/** 题目:hdu4675 GCD of Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675 题意:给定n个数的a数组,以及m,k: ...
- ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)
Description There is a special number sequence which has n+1 integers. For each number in sequence, ...
- 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)
先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...
- ACM学习历程—ZOJ 3868 GCD Expectation(莫比乌斯 || 容斥原理)
Description Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, ...
- ACM学习历程—HYSBZ 2818 Gcd(欧拉函数 || 莫比乌斯反演)
Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...
- ACM学习历程—HDU4746 Mophues(莫比乌斯)
Description As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some ...
- ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...
- ACM学习历程—POJ3090 Visible Lattice Points(容斥原理 || 莫比乌斯)
Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...
随机推荐
- Windows 下Node.js开发环境配置
第一步:安装VirtualBox(以管理员身份安装) 1.安装完成后,打开VirtualBox,点击“新建”按钮,输入信息,“下一步”(名称可任意) 2.设置内存为1024MB,“下一步”—>“ ...
- [note]树链剖分
树链剖分https://www.luogu.org/problemnew/show/P3384 概念 树链剖分,是一种将树剖分成多条不相交的链的算法,并通过其他的数据结构来维护这些链上的信息. 最简单 ...
- zip filter map 列表生成器
map map(function, list): 就是对list 中的每一个元素都调用function函数进行处理,返回一个map的对象 list一下就可以生成一个列表 或者for循环该对象就可以输出 ...
- Js编写的菜单树
只需要提供这种JSON格式就ok了 其他的都可以直接引用这个代码进去 var testMenu=[ { "name": "一级菜单", "submen ...
- test_bdc
[转]REPORT zbdc_test_by_shir. * 定义个BDC格式的内表**************************************************DATA : B ...
- linux 6-find,xargs
十六. 文件查找命令find: 下面给出find命令的主要应用示例: /> ls -l #列出当前目录下所包含的测试文件 -rw-r--r--. 1 root r ...
- ADO.NET概述
xml这类文件它是.net变成环境中优先使用的数据访问借口. ADO.NET传输的数据都是XML格式的 ADO.NET是一组用于和数据源惊醒交互的面向对象类库 数据源:通常是各种数据库,但文本.exc ...
- STM32L0 HAL库 UART 串口读写功能
串口发送功能: uint8_t TxData[]= "01234abcde"; HAL_UART_Transmit(&huart2,TxData,,0xffff);//把T ...
- 禁用chrome浏览器的cookie
Chrome: 1.打开chrome浏览器,点击右上角的“自定义和控制Google Chrome”按钮 2.在下拉菜单中选择设置 3.点击设置页底部的“显示高级设置...” 4.在隐私设置下,点击“内 ...
- [原创]java WEB学习笔记11:HttpServlet(HttpServletRequest HttpServletRsponse) 以及关于 Servlet 小结
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...