• TopCoder 11351 TheCowDivOne


    vj

    考虑生成函数,答案可以写成([x^0y^k]prod_{i=0}^{n-1}(1+x^iy)pmod {x^n-1})

    (=sum_i[x^{in}y^k]prod_{j=0}^{n-1}(1+x^jy))

    (=sum_i[x^iy^k]prod_{j=0}^{n-1}(1+x^jy)[n|i])

    这里单位根反演,原式

    (=frac{1}{n}[y^k]sum_{i=0}^{n-1}prod_{j=0}^{n-1}(1+omega_n^{ij}y))

    然后对于每个(i),后面那坨多项式的形式只和(gcd(i,n))有关,这里改为枚举这个(gcd)的值,原式

    (=frac{1}{n}sum_{d|n}[y^k](prod_{j=0}^{n/d-1}(1+omega_n^{jd}y))^dsum_{j=1}^{n}[gcd(j,n)=d])

    (=frac{1}{n}sum_{d|n}[y^k](prod_{j=0}^{d-1}(1+omega_d^jy))^{n/d}sum_{j=1}^{n}[gcd(j,n)=frac{n}{d}])

    (=frac{1}{n}sum_{d|n}varphi(d)[y^k](1+(-1)^{d+1}y^d)^{n/d})

    然后二项式定理,求出对应组合数即可知道对应的(y^k)的系数.这里的(d)也要满足(d|k)

    btw,下面这个代码不是忘topcoder上交的(

    #include<bits/stdc++.h>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=2000+10,mod=1e9+7;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
        return x*w;
    }
    void ad(int &x,int y){x+=y,x-=x>=mod?mod:0;}
    int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;}return an;}
    int ginv(int a){return fpow(a,mod-2);}
    int n,k,inv[N],d[N],td,phi[N],p[N][2],tt;
    void dfs(int o,int s,int ph)
    {
        if(o>tt){d[++td]=s,phi[td]=ph;return;}
        int ft=1;
        for(int i=0;i<=p[o][1];++i)
    	dfs(o+1,s,ph),s*=p[o][0],ph*=p[o][0]-ft,ft=0;
    }
    int C(int a,int b)
    {
        if(b<0||a<b) return 0;
        int an=1;
        for(int i=1;i<=b;++i) an=1ll*an*(a-i+1)%mod*inv[i]%mod;
        return an;
    }
    
    int main()
    {
        inv[0]=inv[1]=1;
        for(int i=2;i<=N-5;++i) inv[i]=(mod-1ll*mod/i*inv[mod%i]%mod)%mod;
        while(~scanf("%d%d",&n,&k))
        {
        	tt=0;
        	int x=n,sqt=sqrt(n);
        	for(int i=2;i<=sqt;++i)
        	    if(x%i==0)
        	    {
        	    	p[++tt][0]=i,p[tt][1]=0;
        	    	while(x%i==0) x/=i,++p[tt][1];
        	    }
        	if(x>1) p[++tt][0]=x,p[tt][1]=1;
        	td=0,dfs(1,1,1);
        	int ans=0;
        	for(int i=1;i<=td;++i)
        	{
        	    int x=d[i];
        	    if(k%x) continue;
        	    int dx=1ll*phi[i]*C(n/x,k/x)%mod;
        	    ad(ans,((x^1)&(k/x)&1)?mod-dx:dx);
        	}
        	ans=1ll*ans*ginv(n)%mod;
        	printf("%d
    ",ans);
        }
        return 0;
    } 
    
  • 相关阅读:
    解决vue空格换行报错问题
    基本的项目开发流程(前后端开发)
    whl包构建
    Python虚拟环境创建
    页面适配 JS
    SpringBoot整合Ehcache3
    SpringBoot文件分片上传
    SpringBoot访问jar包静态文件
    SpringBoot整合Minio文件存储
    SpringBoot多环境配置文件打包
  • 原文地址:https://www.cnblogs.com/smyjr/p/12610260.html
Copyright © 2020-2023  润新知