• 【BZOJ3601】一个人的数论(数论)


    【BZOJ3601】一个人的数论(数论)

    题面

    BZOJ
    怎么这图片这么大啊。。。

    题解

    要求的是(displaystyle sum_{i=1}^n [gcd(i,n)=1]i^d)
    然后把(gcd=1)给拆了,(displaystyle sum_{i=1}^n i^dsum_{x|i,x|n}mu(x))
    然后再把(mu)丢掉前面去,(displaystyle sum_{x|n}mu(x)x^dsum_{i=1}^{n/x}i^d)
    后面一半是自然数幂和,随便怎么搞都行。然而前面似乎就没法搞了QwQ。
    首先自然数幂和可以写成一个多项式。
    对于(sum_{i}i^d)而言,一定可以写成一个(d+1)次多项式。
    假装这个多项式的系数是(a_i)
    那么式子就可以改写成:(displaystyle sum_{k=0}^d a_ksum_{x|n}mu(x)x^d[frac{n}{x}]^k)
    后面这个东西很明显就是三个积性函数乘起来的,所以后面这个东西也是一个积性函数。
    而现在已经给定了(n)的分解情况,那么只需要对于每个质数求解贡献。
    而每个质因子的出现次数超过(1)的时候贡献就是(0),所以只有出现(0)次或者(1)次的时候有贡献,那么后面这个东西似乎就很好算的样子啦。
    现在的问题就回到了如何求解(a_i)上面。
    这个东西可以待定系数+高斯消元直接爆算出解。
    也可以拉格朗日插值直接算。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MAX 105
    #define MOD 1000000007
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int ans,d,W,a[MAX],p[MAX],b[MAX],c[MAX],pro[MAX];
    int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
    void pre()
    {
    	for(int i=1;i<=d+2;++i)p[i]=(p[i-1]+fpow(i,d))%MOD;b[0]=1;
    	for(int i=0;i<=d+1;++i)
    	{
    		for(int j=i+1;j;--j)b[j]=(b[j-1]+MOD-1ll*b[j]*(i+1)%MOD)%MOD;
    		b[0]=1ll*b[0]*(MOD-i-1)%MOD;
    	}
    	for(int i=0;i<=d+1;++i)
    	{
    		int s=p[i+1],inv=fpow(i+1,MOD-2);
    		for(int j=0;j<=d+1;++j)if(i!=j)s=1ll*s*fpow((i-j+MOD)%MOD,MOD-2)%MOD;
    		b[0]=1ll*b[0]*(MOD-inv)%MOD;
    		for(int j=1;j<=d+2;++j)b[j]=(MOD-1ll*(b[j]+MOD-b[j-1])*inv%MOD)%MOD;
    		for(int j=0;j<=d+2;++j)a[j]=(a[j]+1ll*s*b[j])%MOD;
    		for(int j=d+2;j;--j)b[j]=(b[j-1]+MOD-1ll*b[j]*(i+1)%MOD)%MOD;
    		b[0]=1ll*b[0]*(MOD-i-1)%MOD;
    	}
    }
    int main()
    {
    	d=read();W=read();pre();
    	for(int i=0;i<=d+1;++i)pro[i]=1;
    	while(W--)
    	{
    		int p=read(),v=read(),n=fpow(p,v),inv=fpow(p,MOD-2),pd=fpow(p,d);
    		for(int k=0;k<=d+1;++k)
    		{
    			int ret=(fpow(n,k)+MOD-1ll*pd*fpow(1ll*n*inv%MOD,k)%MOD)%MOD;
    			pro[k]=1ll*pro[k]*ret%MOD;
    		}
    	}
    	for(int i=0;i<=d+1;++i)ans=(ans+1ll*a[i]*pro[i])%MOD;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Codeforces Gym100502H:Clock Pictures(KMP算法)
    SPOJ MINSUB
    POJ 2796:Feel Good(单调栈)
    搭建(WSTMart)php电商环境时缺少fileinfo函数
    TP微信扫码支付
    tp3.2 支付宝app支付
    tp3.2 支付宝手机网站支付
    Thinkphp3.2+PHPQRCode 二维码生成示例
    百度UEditor粘贴或插入的表格不显示边框的解决办法
    PHP:导出数据到word(包含图片)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10503174.html
Copyright © 2020-2023  润新知