【JZOJ4161】于神之怒 莫比乌斯反演
任务
 
 
答案mod 1e9+7.
解法
容易写出反演: 
同时我们还发现,当
所以我们还可以对
总的时间复杂度就是
另外的Trick: 
当我们在对
我们还需预处理出
由于逐个预处理
代码
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<string.h>
#define ll long long
using namespace std;
const char* fin="ex4161.in";
const char* fout="ex4161.out";
const ll inf=0x7fffffff;
const ll maxn=5000007,mo=1e9+7;
ll n,m,N,i,j,k,ans,t;
ll mu[maxn],p[maxn],s[maxn];
bool bz[maxn];
ll qpower(ll a,ll b){
    ll c=1;
    while (b){
        if (b&1) c=c*a%mo;
        a=a*a%mo;
        b>>=1;
    }
    return c;
}
int main(){
    scanf("%d%d%d",&n,&m,&N);
    if (n>m) swap(n,m);
    mu[1]=1;
    s[1]=1;
    for (i=2;i<maxn;i++){
        if (!bz[i]){
            mu[i]=-1;
            s[i]=qpower(i,N);
            p[++p[0]]=i;
        }
        for (j=1;j<=p[0];j++){
            k=i*p[j];
            if (k>=maxn) break;
            bz[k]=true;
            s[k]=s[i]*s[p[j]]%mo;
            if (i%p[j]==0){
                mu[k]=0;
                break;
            }else mu[k]=-mu[i];
        }
    }
    for (i=1;i<maxn;i++){
        mu[i]+=mu[i-1];
        s[i]=(s[i-1]+s[i])%mo;
    }
    ll cnt=0;
    for (ll T=1;T<=n;){
        t=min(n/(n/T),m/(m/T));
        ll tmp=0,tmd=n/T,tmb=m/T;
        for (i=1;i<=tmd;){
            cnt++;
            j=min(tmd/(n/(i*T)),tmb/(m/(i*T)));
            tmp=(tmp+(tmd/i)*(tmb/i)*(mu[j]-mu[i-1]))%mo;
            i=j+1;
        }
        ans=(ans+tmp*(s[t]-s[T-1]))%mo;
        T=t+1;
    }
    ans=(ans%mo+mo)%mo;
    printf("%lld",ans);
    return 0;
}Warning
注意卡常,先预算出
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号