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(莫比乌斯)的更多相关文章

  1. 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) = ...

  2. hdu4675 GCD of Sequence 莫比乌斯+组合数学

    /** 题目:hdu4675 GCD of Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675 题意:给定n个数的a数组,以及m,k: ...

  3. ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)

    Description There is a special number sequence which has n+1 integers. For each number in sequence, ...

  4. 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)

    先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...

  5. ACM学习历程—ZOJ 3868 GCD Expectation(莫比乌斯 || 容斥原理)

    Description Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, ...

  6. ACM学习历程—HYSBZ 2818 Gcd(欧拉函数 || 莫比乌斯反演)

    Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...

  7. ACM学习历程—HDU4746 Mophues(莫比乌斯)

    Description As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some ...

  8. ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...

  9. ACM学习历程—POJ3090 Visible Lattice Points(容斥原理 || 莫比乌斯)

    Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...

随机推荐

  1. 让WebRTC支持H264编解码

    近期实验了下怎样让WebRTC支持H264编码.记录下,供有须要的人參考. 说明一下,我是在 Ubuntu Server 14.04 下编译的 WebRTC ,使用 native(C++) api 开 ...

  2. Card Collector

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

  3. PHP开发环境搭建(转载)

    转载自:http://blog.csdn.net/rosetta/article/details/53967215 前言   最近学了n种语言,学每种语言的套路无非就是先搭建一个开发环境,再找本书或者 ...

  4. Webpack探索【2】--- 安装、项目初始化、webpack.config.js配置文件

    本文主要讲安装.项目初始化.webpack.config.js配置文件方面的内容.

  5. python中TCP和UDP区别

    TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用TCP的应用:Web浏览 ...

  6. mysql 大数据 查询方面的测试

    ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千 ...

  7. 【TFS】解决TFS编译中文乱码问题

    前言; TFS2018做程序集成非常方便,线上编译然后直接生成docker镜像,但是在使用过程中遇到编译窗口中文乱码的问题,这个问题找了好久没人知道怎么解决.如下: 这个问题不解决,每次编译失败,研发 ...

  8. RLearning第1弹:初识R语言

    R作为一种统计分析软件,是集统计分析与图形显示于一体的.体积小.开源.很强的互动性.自从学了R本人就很少再用matlab了... 一.R语言由函数和赋值构成. R使用<-(最好养成使用习惯),而 ...

  9. 模仿jquery框架源码 -成熟---选择器

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  10. 每天一个Linux命令(6)rmdir命令

         rmdir命令用来删除空目录. 利用rmdir命令可以从一个目录中删除一个或多个空的子目录.该命令从一个目录中删除一个或多个子目录,其中dirname表示目录名.如果dirname中没有指定 ...