线性筛积性函数+反演T套路——bzoj4407

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define maxn 5000005
ll n,m,K;

ll Pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b%2)res=res*a%mod;
        b>>=1;a=a*a%mod;
    }
    return res;
}
bool vis[maxn];
ll prime[maxn],G[maxn],sum[maxn],mu[maxn],mm;
void init(){
    mu[1]=G[1]=1;
    for(int i=2;i<maxn;i++){
        if(!vis[i]){
            prime[++mm]=i;
            mu[i]=-1;
            G[i]=Pow(i,K)-1;
            if(G[i]<0)G[i]+=mod;
        }
        for(int j=1;j<=mm;j++){
            if(i*prime[j]>=maxn)break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0){
                mu[i*prime[j]]=0;
                G[i*prime[j]]=G[i]*Pow(prime[j],K)%mod;
                break;
            }
            else {
                mu[i*prime[j]]=-mu[i];
                G[i*prime[j]]=G[i]*G[prime[j]]%mod;
            }
        }
    }
    for(int i=1;i<maxn;i++)
        sum[i]=(sum[i-1]+G[i])%mod;
}

int main(){
    int t;cin>>t>>K;
    init();
    while(t--){
        cin>>n>>m;
        if(n>m)swap(n,m);
        ll ans=0;
        for(int l=1,r;l<=n;l=r+1){
            r=min(n/(n/l),m/(m/l));
            ll tmp=((sum[r]-sum[l-1])%mod+mod)%mod;
            ans=(ans+tmp*(n/l)%mod*(m/l)%mod)%mod;
        }
        cout<<ans<<'\n';
    }
}

 

posted on 2019-07-08 18:04  zsben  阅读(174)  评论(0编辑  收藏  举报

导航