• 于神之怒加强版


    vi.于神之怒加强版

    在这之前,我们引出一个数论函数\(id^k(x)=x^k\)。这个函数就是整数域上的\(k\)次函数。很明显,它是积性函数,准确地说,是完全积性函数

    它的两个特例,一是\(k=1\),就是我们之前提到的\(id\)函数。二是\(k=0\),即\(id^0\)函数。因为\(\forall x\in\mathbb{N}^+,id^0(x)=1\),因此这个函数有一个形象的名字:“1函数”,即\(1(x)\)

    在上一题中,我们最大的任务是求出\(\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)\),而这个东西,我们有\(\sqrt{n}\)复杂度的\(\sum\limits_{T=1}^{\min(n,m)}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor((id*\mu)(T))\)

    在这道题中,\(\gcd(i,j)\)变成了\(\gcd^k(i,j)\)。相应地,如果你把它再证明解一遍的话,就会发现这道题的答案为\(\sum\limits_{T=1}^{\min(n,m)}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor((id^k*\mu)(T))\)

    显然,后面的东西是积性函数。我们设\(g=id^k*\mu\)

    因为\(g\)是积性函数,所以如果有\(x=\prod\limits_{i=1}^n(P_i)^{a_i}\),那么\(g(x)=\prod\limits_{i=1}^ng((P_i)^{a_i})\)

    代入\(g\)的定义:\(g(T)=\sum_{d|T}id^k(d)\mu({\dfrac{T}{d}})\),得\(g(x)=\prod\limits_{i=1}^n\sum_{d|(P_i)^{a_i}}id^k(d)\mu({\dfrac{(P_i)^{a_i}}{d}})\)

    \(d<P_i^{a_i-1}\)时,\(\mu({\dfrac{(P_i)^{a_i}}{d}})=0\)。因此我们只用考虑\(d=P_i^{a_i-1}\)\(P_i^{a_i}\)

    \(g(x)=\prod\limits_{i=1}^nid^k(P_i^{a_i-1})\mu(P_i)+id^k(P_i^{a_i})\mu(1)\)

    代入\(id^k\)\(\mu\)的定义,得\(g(x)=\prod\limits_{i=1}^n(P_i^{(a_i-1)*k})*(-1)+(P_i^{a_i*k})*1\)

    则有\(g(x)=\prod\limits_{i=1}^n(P_i^{(a_i-1)*k})*(P_i^{a_i}-1)\)。依照这个定义,我们就可以写出线性筛的程序了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    int T,n,m,k,g[5001000],f[5001000],pri[5001000],res;
    int ksm(int x,int y){
    	int res=1;
    	for(;y;x=(1ll*x*x)%mod,y>>=1)if(y&1)res=(1ll*res*x)%mod;
    	return res;
    }
    void getg(int N){
    	g[1]=1;
    	for(int i=2;i<=N;i++){
    		if(!pri[i])pri[++pri[0]]=i,f[pri[0]]=ksm(i,k),g[i]=(f[pri[0]]-1+mod)%mod;
    		for(int j=1;j<=pri[0]&&1ll*i*pri[j]<=N;j++){
    			pri[i*pri[j]]=true;
    			if(!(i%pri[j])){
    				g[i*pri[j]]=1ll*g[i]*f[j]%mod;
    				break;
    			}
    			g[i*pri[j]]=1ll*g[pri[j]]*g[i]%mod;
    		}
    	}
    	for(int i=1;i<=N;i++)g[i]=(g[i-1]+g[i])%mod;
    }
    int main(){
    	scanf("%d%d",&T,&k),getg(5000000);
    	while(T--){
    		scanf("%d%d",&n,&m),res=0;
    		for(int l=1,r;l<=min(n,m);l=r+1)r=min(n/(n/l),m/(m/l)),(res+=1ll*(g[r]-g[l-1]+mod)%mod*(n/l)%mod*(m/l)%mod)%=mod;
    		printf("%d\n",res);
    	}
    	return 0;
    }
    

  • 相关阅读:
    Redis和Lombok的下载安装
    (五)模仿学习完成后台管理页面删除
    (六)模仿学习后台管理页面添加
    模拟学习动漫论坛合集
    (八)模仿学习展现可视化大屏
    基于C/S 结构的IM即时通讯软件下篇
    排序算法之基排
    qt学习001之运行对话框
    每日一练之大整数加法(P1255 数楼梯)
    每日算法之递推排序(P1866 编号)
  • 原文地址:https://www.cnblogs.com/Troverld/p/14619552.html
Copyright © 2020-2023  润新知