• 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;
    }
    View Code
  • 相关阅读:
    前端使用crypto.js进行加密
    C#编程总结(七)数据加密——附源码
    PID file /run/zabbix/zabbix_server.pid not readable (yet?) after start. 报错解决
    TNS-12560: Message 12560 not found; No message file for product=network, facility=TNS报错
    oracle无法启动asm实例记录
    linux添加硬盘分区挂载教程
    Oracle Database 12c Release 2安装过程实录
    Centos6.9minimal版系统安装图形化界面
    扫描工具nmap介绍
    Zabbix系列之六——添加web监测
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4975570.html
Copyright © 2020-2023  润新知