HDU6390 GuGuFishtion

队友告诉我一个结论,phi(ab)/phi(a)phi(b)=gcd(ab)/phi(gcd(a,b)),那么我们发现这道题做完了。枚举gcd就行了,变成了NOI2010能量采集,然而当时我写的复杂度是nsqrt(n),并过不掉这题,于是队友写出了nlogn复杂度,发现还是T。。。于是我找到一篇NOI2010能量采集O(n)的题解https://blog.csdn.net/ThinFatty/article/details/78481516,抄下来改一改就A了= =,phi值先线性预处理一蛤

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e6+5;

LL pri[maxn],phi[maxn],mu[maxn],sum[maxn],cnt,n,m,P;
LL inv[maxn],S[maxn];
bool vis[maxn]; 

inline void get()
{
    phi[1]=1;
    mu[1]=1;
    cnt=0;
    for(int i=2;i<=1e6;++i)
    {
        if(!vis[i])pri[++cnt]=i,phi[i]=i-1,mu[i]=-1;
        for(int j=1;j<=cnt&&i*pri[j]<=1e6;++j)
        {
            vis[i*pri[j]]=1;
            phi[i*pri[j]]=phi[i]*phi[pri[j]];
            mu[i*pri[j]]=0;
            if(i%pri[j]==0)
            {
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            mu[i*pri[j]]-=mu[i];
        }
    }
}

inline LL calc(LL n,LL m)
{
    LL res=0;
    for(int i=1,last=0;i<=n;i=last+1)
    {
        last=min(n/(n/i),m/(m/i));
        res+=(sum[last]-sum[i-1])*(n/i)*(m/i);
    }
    return res;
}

inline LL Pow(LL a,LL b)
{
    LL ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%P;
        a=a*a%P;
        b>>=1; 
    }
    return ans;
}

inline LL sol(LL n,LL m)
{
    if(n>m)swap(n,m);
    LL ans=0;
    inv[0]=inv[1]=1;
    int mx=min(P,n);
    for(int i = 2; i <= mx; ++i)    
        inv[i] = (P - (P / i)) * inv[P % i] % P;
    for(int i = 1; i<=n ;++i)
        S[i]=(S[i-1]+1ll*i*inv[phi[i]]%P)%P;
    
    for (int i=1,last;i<=n;i=last+1)
    {
        last=min(n/(n/i),m/(m/i));
        LL t=(S[last]-S[i-1]+P)%P;
        //LL t=(LL)(last+i)*(last-i+1)/2LL;
        //printf("%lld\n",calc(n/i,m/i));
        //ans+=calc(n/i,m/i,tmp/i)*t;
        ans=(ans+1ll*calc(n/i,m/i)%P*t%P)%P;
    }
    return ans%P;
}

int main()
{
    int t;
    scanf("%d",&t);
    get();
    for(int i=1;i<=1e6;++i)sum[i]=sum[i-1]+mu[i];
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&m,&P);
        printf("%lld\n",sol(n,m));
    }
    return 0;    
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/81667892