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, x2, ..., xn的最大公约数。

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

Input

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

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

Output

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

Sample Input

3 3 3
3 3 3

Sample Output

7 1 0

HINT

当d=1,{b[n]}可以为:(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), (2, 1, 1), (2, 1, 2), (2, 2, 1)。

当d=2,{b[n]}可以为:(2, 2, 2)。

当d=3,因为{b[n]}必须要有k个数与{a[n]}不同,所以{b[n]}不能为(3, 3, 3),满足条件的一个都没有。

对于100%的数据,1<=N,M<=300000, 1<=K<=N, 1<=a[i]<=M。

首先gcd=x的答案可以转化成gcd为x因数的答案,再容斥相减。

那么我们现在要求的就是,对于1到M的每个整数d,有多少个不同的数列b[1], b[2], ..., b[N],满足:

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

(2)(b[1], b[2], ..., b[N])均是d的倍数;

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

然后发现顺序与答案无关。

枚举d,计算有多少a[i]是d的倍数以及有多少[1,m]中的数是d的倍数x。那么要从a[i]中选出n-k个数保留,剩下a[i]中的有x-1中选择,最后的有x种选择。

时间复杂度O(nlogn)

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
    return x*f;
}
typedef long long ll;
const int maxn=300010;
const int mod=1000000007;
int n,m,k,S[maxn];
ll ans[maxn],xp[maxn],inv[maxn];
ll pow(int a,int n) {
    if(!n) return 1;
    ll ans=pow(a,n>>1);
    (ans*=ans)%=mod;if(n&1) (ans*=a)%=mod;
    return ans;
}
int main() {
    n=read();m=read();k=n-read();
    rep(i,1,n) S[read()]++;
    xp[0]=inv[0]=1;
    rep(i,1,n) xp[i]=(xp[i-1]*i)%mod,inv[i]=(inv[i-1]*pow(i,mod-2))%mod;
    rep(i,1,m) {
        int cnt=0,tot=0;
        for(int j=i;j<=m;j+=i) cnt+=S[j],tot++;
        if(cnt>=k) ans[i]=pow(tot-1,cnt-k)*pow(tot,n-cnt)%mod*xp[cnt]%mod*inv[k]%mod*inv[cnt-k]%mod;
    }
    dwn(i,m,1) for(int j=2*i;j<=m;j+=i) ans[i]=(ans[i]-ans[j]+mod)%mod;
    printf("%lld",ans[1]);rep(i,2,m) printf(" %lld",ans[i]);
    return 0;
}

时间: 2024-08-04 02:17:54

BZOJ4305: 数列的GCD的相关文章

【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

【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的最大公

数列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}

dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:655   Accepted:54 [Submit][Status][Discuss] Description 已知一个长度为 n 的数组 a[1],a[2],-,a[n],我们进行 q 次询问,每次询问区间 a[l],a[l+1],-,a[r?1],a[r] ,数字从小到大

hdu 6025 前缀 后缀 gcd

大致题意: 去掉一个元素能使这个数列的GCD最大为多少 分析: 我们求一个数列的GCD,是先求前两个元素的GCD,然后将这个GCD值在与下一个元素进行GCD运算.由此可知进行GCD运算的顺序对最终的结果是没有影响的.我们再看看数列的长度范围,小于100000.那我们就枚举去掉的那个元素,那么去掉元素后的数列的GCD即这个元素前面一段数列的GCD再与这个元素后面一段数列的GCD进行GCD运算.所以我们需要两个数组分别记录前缀GCD和后缀GCD,这两个数组都可以通过O(n)算法算出来. #inclu

[题解]第十一届北航程序设计竞赛预赛——D.最大公约数

题目描述 给一个长度为n(1<=n<=100000)的正整数列,分成尽量多的非空段,使得每一段的最大公约数相等.一个数的最大公约数是它本身. 解题思路 要求每一段子列的gcd相等,不妨设为d,可以知道d是所有数的最大公约数,即d=(a[1],a[2],……,a[n]).于是我们先求出d,然后从前往后扫描,记st=1,移动ed,计算d1=(a[st],……,s[ed]),直到d1==d,得到的区间[st,ed]就是一个符合题目要求的子列:记st=ed+1,重复上述操作,直至数列扫完.算法时间复杂

Pagodas 等差数列

nn pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, labelled from 11 to nn. However, only two of them (labelled aa and bb, where 1≤a≠b≤n1≤a≠b≤n) withstood the test of time. Two monks, Yuwgna and Iaka, d

2017.12.09【NOIP提高组】模拟赛A组

2017.12.09[NOIP提高组]模拟赛A组 T1 3489. [NOIP2013模拟联考11]数列的GCD(gcd) T2 3500.[NOIP2013模拟联考15]物语(monogatari) T3 3501.[NOIP2013模拟联考15]消息传递(news) 吐槽:这次的题好像有点水啊,但最简单的第二题都给打挂啦!!(数组开小了) T1 本套题中最难的题.考虑dp 设f[i]是b[1],b[2]...b[N]的最大公约数的数目,g[i]是b[1],b[2]...b[N]的公约数的数目