【bzoj4305】数列的GCD 组合数学+容斥原理

题目描述

给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N)。

现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], b[2], ..., b[N],满足:

(1)1<=b[i]<=M(1<=i<=N);

(2)gcd(b[1], b[2], ..., b[N])=d;

(3)恰好有K个位置i使得a[i]≠b[i](1<=i<=N)

注:gcd(x1,x2,...,xn)为x1, x2, ..., xn的最大公约数。

输出答案对1,000,000,007取模的值。

输入

第一行包含3个整数,N,M,K。

第二行包含N个整数:a[1], a[2], ..., a[N]。

输出

输出M个整数到一行,第i个整数为当d=i时满足条件的不同数列{b[n]}的数目mod 1,000,000,007的值。

样例输入

3 3 3
3 3 3

样例输出

7 1 0



题解

数学+容斥

老套路了,先处理出 $\gcd$ 为 $d$ 的倍数的方案数:

预处理出 $\{a[n]\}$ 中 $d$ 的倍数的数目 $c[d]$ ,那么 $d$ 的倍数中需要有 $n-k$ 个与 $\{a[n]\}$ 相同,有 $C_{c[d]}^{n-k}$ 种方案。

其余 $c[d]-n+k$ 个 $d$ 的倍数每个都有 $\lfloor\frac md\rfloor-1$ 种方案,因为 $d$ 的倍数总共有 $\lfloor\frac md\rfloor$ 个,减去不能等于原序列的1个。

剩下 $n-c[d]$ 个非 $d$ 的倍数的每个有 $\lfloor\frac md\rfloor$ 种方案。

因此 $\gcd$ 为 $d$ 的倍数的方案数就是 $C_{c[d]}^{n-k}\times(\lfloor\frac md\rfloor -1)^{c[d]-n+k}\times(\lfloor\frac md\rfloor)^{n-c[d]}$ 。

然后这个答案需要容斥一下,减去 $d$ 的2以上倍数的答案。

即 $ans[d]=C_{c[d]}^{n-k}\times(\lfloor\frac md\rfloor -1)^{c[d]-n+k}\times(\lfloor\frac md\rfloor)^{n-c[d]}-\sum\limits_{i=2}^{\lfloor\frac md\rfloor}ans[i\times d]$ 。

从大到小循环 $d$ ,后面的 $ans$ 已经求出,直接减掉即可,不需要莫比乌斯反演。

由于数的范围只有 $m=300000$ ,因此每一步都可以调和级数预处理。

时间复杂度 $O(n\log n)$

#include <cstdio>
#define N 300010
#define mod 1000000007
typedef long long ll;
int a[N] , v[N] , c[N];
ll fac[N] , ans[N];
inline ll pow(ll x , int y)
{
	ll ans = 1;
	while(y)
	{
		if(y & 1) ans = ans * x % mod;
		x = x * x % mod , y >>= 1;
	}
	return ans;
}
int main()
{
	int n , m , k , i , j;
	scanf("%d%d%d" , &n , &m , &k) , k = n - k;
	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , v[a[i]] ++ ;
	for(i = 1 ; i <= m ; i ++ )
		for(j = 1 ; i * j <= m ; j ++ )
			c[i] += v[i * j];
	fac[0] = 1;
	for(i = 1 ; i <= n ; i ++ ) fac[i] = fac[i - 1] * i % mod;
	for(i = m ; i ; i -- )
	{
		if(c[i] >= k) ans[i] = fac[c[i]] * pow(fac[k] , mod - 2) % mod * pow(fac[c[i] - k] , mod - 2) % mod * pow(m / i - 1 , c[i] - k) % mod * pow(m / i , n - c[i]) % mod;
		for(j = 2 ; i * j <= m ; j ++ ) ans[i] = (ans[i] - ans[i * j] + mod) % mod;
	}
	for(i = 1 ; i < m ; i ++ ) printf("%lld " , ans[i]);
	printf("%lld\n" , ans[m]);
	return 0;
}

原文地址:https://www.cnblogs.com/GXZlegend/p/8495715.html

时间: 2024-11-03 21:37:22

【bzoj4305】数列的GCD 组合数学+容斥原理的相关文章

BZOJ4305: 数列的GCD

Description 给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N). 现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], b[2], ..., b[N],满足: (1)1<=b[i]<=M(1<=i<=N): (2)gcd(b[1], b[2], ..., b[N])=d: (3)恰好有K个位置i使得a[i]<>b[i](1<=i<=N) 注:gcd(x1,x2,...,xn)为x1, x

HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)

GCD Problem 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) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output t

HDU 1796 How many integers can you find(组合数学-容斥原理)

How many integers can you find Problem Description Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer

【BZOJ 4305】 4305: 数列的GCD (数论)

4305: 数列的GCD Description 给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N). 现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], b[2], ..., b[N],满足: (1)1<=b[i]<=M(1<=i<=N): (2)gcd(b[1], b[2], ..., b[N])=d: (3)恰好有K个位置i使得a[i]<>b[i](1<=i<=N) 注:gcd(x1,x2,

BZOJ 4305: 数列的GCD( 数论 )

对于d, 记{ai}中是d的倍数的数的个数为c, 那么有: 直接计算即可,复杂度O(NlogN+MlogM) --------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const in

uva 10325 The Lottery(组合数学-容斥原理)

 The Lottery  The Sports Association of Bangladesh is in great problem with their latest lottery 'Jodi laiga Jai'. There are so many participants this time that they cannot manage all the numbers. In an urgent meeting they have decided that they will

HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题目解析: Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. 题目又说a==c==1,所以就是求[1,b]与[1,d]中gcd等于k的个数,因为若gcd(x,y)==z,那么gcd(x/z,y/z)==1,又因为不是z的倍数的肯定不是,所以不是z的倍数的可以直接去

UESTC - 1544 当咸鱼也要按照基本法 组合数学 容斥原理

http://acm.uestc.edu.cn/#/problem/show/1544 考虑一下2.2.2这样的情况.答案应该是n / 2 如果只选一个的情况下,对答案的贡献是正的,但是这里有三个,也就是我们统计了3 * n / 2,统计多了. 那么对于任选两个数的情况,有三种,(2, 2) * 3,分别都是不同位置的2, /**************************************/ 我做的时候是发现,先讨论只有 2.2的情况,也就是只有两个数的时候,ans = 0,这个时候

数列GCD

数列 GCD 数列的 GCD 具有一些很迷人的性质, 值得我用一个完整的页面阐述. 一般地, GCD 具有可并性: 设有互不相交的多重集合 S, T , 则 $gcd(S \cup T) = gcd(gcd(S), gcd(T))$ . 如果我们给定一个数列 $A$ , 要求某个区间的 gcd , 那么就可以使用线段树, ST 表等区间合并的结构, 在 $O(\log n)$ 或 $O(\log ^ 2 n)$ 求解. 数列的 GCD 还具备更多的性质. 为了方便阐述, 设 $S_{l, r}