BZOJ 4305 series of GCD

Topic links: the Click here Wallpaper

Solution:

Set \ (f [i] \) means that when \ (d = i \) answers when, \ (C [I] \) represents \ (A \) sequence how many \ (I \) multiple

First, we make exactly \ (K \) number different from each other, the other represents \ (NK \) number exactly the same, then there is \ ({c [i] \ choose nk} \) kinds of programs

Consider the remaining \ (c [i] -n + k \) bits \ (I \) position multiple, \ ([. 1, m] \) in \ (I \) multiples have \ (\ lfloor {m \ over i} \ rfloor \) a, but not identical, to subtract themselves, i.e., program number \ ((\ lfloor {m \ over i} \ rfloor-1) ^ {c [i] -n + } K \) , the rest position of the same reason, but not subtracting themselves, i.e. $ \ lfloor {m \ over i } \ rfloor ^ {nc [i]} $

Here we find that we not only counted \ (i \) own, also \ (i \) multiples are also enumerated, so to lose, then
\ [f [i] = { c [i] \ choose nk } \ times (\ lfloor {m \ over i} \ rfloor -1) ^ {c [i] -n + k} \ times \ lfloor {m \ over i} \ rfloor ^ {nc [i]} - \ sum_ {j = 2} ^ {\
lfloor {m \ over i} \ rfloor} f [i \ times j] \] so we can count backwards, time complexity \ ((n \ log n O ) \)

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
const int N=3e5+11;
int n,m,k,a[N],f[N],c[N],v[N];
int fac[N]={1},ifac[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int qpow(int x,int y){
    int re=1;
    while(y>0){
        if(y&1) re=re*x%mod;
        y>>=1;x=x*x%mod;
    }return re;
}
int C(int x,int y){
    if(x<y) return 0;
    return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
signed main(){
    n=read(),m=read(),k=read();
    for(int i=1;i<=n;i++) ++v[a[i]=read()];
    for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
    ifac[n]=qpow(fac[n],mod-2);ifac[0]=1;
    for(int i=n-1;i;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
    for(int i=1;i<=m;i++)
        for(int j=1;j*i<=m;j++)
            c[i]+=v[i*j];
    for(int i=m;i;i--){
        f[i]=C(c[i],n-k)*qpow(m/i-1,c[i]-n+k)%mod;
        f[i]=f[i]*qpow(m/i,n-c[i])%mod;
        for(int j=2;j<=m/i;j++) f[i]=(f[i]+mod-f[i*j])%mod;
    }
    for(int i=1;i<=m;i++) printf("%lld ",f[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/NLDQY/p/12241870.html
gcd