B - GuGuFishtion(莫比乌斯 欧拉函数 预处理mu函数的欧拉函数的模板)

题目链接:https://cn.vjudge.net/contest/270608#problem/B

题目大意:题目中说,就是对欧拉函数的重新定义的一种函数的求和.

证明方法:

 

AC代码:

#include<iostream>
#include<stack>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<queue>
#include<algorithm>
#include<stdio.h>
#include<string>
#include<map>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 1000000+100;
ll n,m,mod;
ll prime[maxn],phi[maxn],a[maxn];
int mu[maxn];
ll inv[maxn];
ll len;
bool flag[maxn];
void init()
{
    phi[1]=1;
    mu[1]=1;
    int cnt=0;
    for(int i=2; i<maxn; i++)
    {
        if(!flag[i])
        {
            prime[cnt++]=i;
            phi[i]=i-1;
            mu[i]=-1;
        }
        for(int j=0; j<cnt; j++)
        {
            ll temp=i*prime[j];
            if(temp>maxn)break;
            flag[temp]=1;
            if(i%prime[j]==0)
            {
                phi[temp]=phi[i]*prime[j];
                mu[temp]=0;
                break;
            }
            else
            {
                phi[temp]=phi[i]*(prime[j]-1);
            }
            mu[temp]=-mu[i];
        }
    }
}
void gao()
{
    inv[1]=1;
    for(int i=2; i<=len; i++)
    {
        inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    }
    for(int i=1; i<=len; i++)
    {
        a[i]=i*inv[phi[i]]%mod;
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    init();
    while(T--)
    {
        scanf("%lld %lld %lld",&m,&n,&mod);
        len=min(n,m);
        gao();
        ll ans=0;
        for(int i=1; i<=len; i++)
        {
            int t1=m/i,t2=n/i;
            int v=min(t1,t2);
            ll g=0;
            for(int j=1; j<=v; j++)
            {
                g=(g+mu[j]*(t1/j)%mod*(t2/j)+mod)%mod;
            }
            ans=(ans+a[i]*g)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2018-12-08 11:12  Let_Life_Stop  阅读(264)  评论(0编辑  收藏  举报