bzoj3561: DZY Loves Math VI

这简直就是一个!@#¥%……&*(sb题我都~!@#$%T^&*

随便枚举gcd乱推柿子完事,我还想了贼久怎么加速自然数幂和

结果告诉我直接暴力搞完事,sigema(min/d)约等于ln(n) !!!????

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=5e5+_;
const LL mod=1e9+7;
LL quick_pow(LL A,int p)
{
    LL ret=1;
    while(p!=0)
    {
        if(p%2==1)ret=ret*A%mod;
        A=A*A%mod;p/=2;
    }
    return ret;
}

int pr,prime[maxn];bool v[maxn];
int u[maxn];
void get_prime()
{
    u[1]=1;
    for(int i=2;i<maxn;i++)
    {
        if(v[i]==false)
        {
            prime[++pr]=i;
            u[i]=-1;
        }
        for(int j=1;j<=pr&&i*prime[j]<maxn;j++)
        {
            v[i*prime[j]]=true;
            if(i%prime[j]==0)
                {u[i*prime[j]]=0;break;}
            u[i*prime[j]]=-u[i];
        }
    }
}

LL md[maxn],s[maxn];
int main()
{
    get_prime();
    int n,m;
    scanf("%d%d",&n,&m);
    LL ans=0; int li=min(n,m);
    for(int d=1;d<=li;d++)
    {
        int li2=max(n,m)/d;
        for(int i=1;i<=li2;i++)
            md[i]=(d==1)?i:(md[i]*i%mod),s[i]=(s[i-1]+md[i])%mod;
        
        LL sum=0;
        for(int k=1;k<=li2;k++)
        {
            sum+=u[k]*md[k]*md[k]%mod*s[n/d/k]%mod*s[m/d/k]%mod;
            if(sum>=mod)sum-=mod;
            else if(sum<0)sum+=mod;
        }
        ans+=sum*quick_pow(d,d)%mod;
        if(ans>=mod)ans-=mod;
    }
    printf("%lld
",ans);
    
    return 0;
}
原文地址:https://www.cnblogs.com/AKCqhzdy/p/10594431.html