zoukankan      html  css  js  c++  java
  • 【LGP4714】「数学」约数个数和

    题目

    众所周知,除数个数函数(sigma_0=I^2)(I)就是狄利克雷卷积里的(1)函数

    于是熟悉狄利克雷卷积的话很快就能看出我们要求的就是(I imes I^{k}),即(I^{k+1}),我们给这个函数起一个名字叫(f^{k+1})

    显然这个东西是积性函数,于是我们考虑一下指数次幂的(f)如何求

    显然

    [f^{k+1}(n)=sum_{d|n}f^{k}(d) ]

    对于指数次幂(p^m)

    [f^{k+1}(p^m)=sum_{i=0}^mf^k(p^i) ]

    我们考虑一下快速求(f^{k+1}(p^m)),发现就是就是把这(m)次幂分配到(k+1)次减少的机会里去,当然最后不一定减少到(0),于是等价于把(m)个球分给(k+2)个盒子,允许为空,插板一下得知这个是(inom{k+m+1}{m+1}),我们发现这个组合数非常好算,于是直接暴力就好了,由于又是积性函数,我们分解质因数之后直接合并就可以了

    代码

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register
    #define min std::min
    #define LL long long
    const int maxn=1e7+5;
    const int mod=998244353;
    int f[maxn],p[maxn>>2],inv[505];
    LL n,m;int T,ans=1;
    inline int C(LL n,int m) {
    	int now=1;
    	for(re int i=n;i>=n-m+1;--i) now=1ll*now*(i%mod)%mod;
    	for(re int i=1;i<=m;i++) now=1ll*now*inv[i]%mod;
    	return now;
    }
    int main() {
    	scanf("%lld%lld",&n,&m);inv[1]=1;
    	for(re int i=2; i<505; i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    	f[1]=1;T=std::sqrt(n)+1;T=min(T,maxn-1);
    	for(re int i=2;i<=T;i++) {
    		if(!f[i]) p[++p[0]]=i;
    		for(re int j=1;j<=p[0]&&p[j]*i<=T;j++) {
    			f[p[j]*i]=1;
    			if(i%p[j]==0) break;
    		}
    	}
    	p[++p[0]]=1e9+7,p[++p[0]]=998244353,p[++p[0]]=1e9+9;
    	for(re int i=1;i<=p[0];i++) {
    		int t=0;
    		while(n%p[i]==0) n/=p[i],t++;
    		if(!t) continue;
    		ans=1ll*ans*C((t+m+1)%mod,t)%mod;
    	}
    	if(n!=1) ans=1ll*ans*C(m+2,1)%mod;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    SQL怎么随机提取出一条信息 mysql 获取随机记录
    css3 渐变 各浏览器兼容
    php的curl和socket的区别 转
    php获取本机真实IP地址
    SSH超时断开 ssh 老掉线
    php 获取远程服务器信息 get_headers 的使用
    如何删除右键菜单中的Catalyst(TM) Control Center选项
    多线程概念、案例!
    网络编程
    我的博客开通啦
  • 原文地址:https://www.cnblogs.com/asuldb/p/11044730.html
Copyright © 2011-2022 走看看