LUOGU P2568 GCD

Here

仅作笔记和理解

算是莫比乌斯模板题了吧
话不多说推式子

*除法皆默认向下取整

∑ g ∈ p r i m e ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = = g ] \sum\limits_{g∈prime}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[gcd(i,j)==g] gprimei=1nj=1n[gcd(i,j)==g]

∑ g ∈ p r i m e ∑ i = 1 n g ∑ j = 1 n g [ g c d ( i , j ) = = 1 ] \sum\limits_{g∈prime}\sum\limits_{i=1}^{\frac{n}{g}}\sum\limits_{j=1}^{\frac{n}{g}}[gcd(i,j)==1] gprimei=1gnj=1gn[gcd(i,j)==1]

∑ g ∈ p r i m e ∑ i = 1 n g ∑ j = 1 n g ∑ d ∣ g c d ( i , j ) μ ( d ) \sum\limits_{g∈prime}\sum\limits_{i=1}^{\frac{n}{g}}\sum\limits_{j=1}^{\frac{n}{g}}\sum\limits_{d|gcd(i,j)}μ(d) gprimei=1gnj=1gndgcd(i,j)μ(d)

∑ g ∈ p r i m e ∑ d = 1 n g μ ( d ) ⌊ n g d ⌋ 2 \sum\limits_{g∈prime}\sum\limits_{d=1}^{\frac{n}{g}}μ(d)\lfloor\frac{n}{gd}\rfloor^{2} gprimed=1gnμ(d)gdn2

然后按照 n g \frac{n}{g} gn整除分块就行了

懂的都懂

Code 481MS

/****************************
* Author : 水娃             *
* Date : 2020-08-19-13.02.04*
****************************/
#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define ll long long
#define debug(a) cout<<#a<<" is "<
#define ull unsigned long long
#define fi first
#define se second
typedef pair<int,int>pii;
typedef pair<ll,int>pli;
typedef pair<int,ll>pil;
typedef pair<ll,ll>pll;
const ll mo=(ll)1e9+7;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
const int MAXN=1e7+100;
int now,mn;
int mu[MAXN];
int pri[MAXN>>1];
bool vis[MAXN];
void pre()
{
    now=0;
    mu[1]=1;
    for(int i=2;i<mn;i++)
    {
        if(!vis[i])
        {
            pri[++now]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=now&&i*pri[j]<mn;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j])
            {
                mu[i*pri[j]]=-mu[i];
            }
            else
            {
                mu[i*pri[j]]=0;
                break;
            }
        }
    }
    for(int i=1;i<mn;i++)
    {
        mu[i]+=mu[i-1];
    }
}
ll n;
ll getans(ll p)
{
    ll l,r,top=n/p,tmpans=0;
    for(l=1;l<=top;l=r+1)
    {
        r=top/(top/l);
        tmpans+=(top/l)*(top/l)*(mu[r]-mu[l-1]);
    }
    return tmpans;
}
void work()
{
    cin>>n;
    mn=n+100;
    pre();
    ll ans=0;
    for(int i=1;i<=now&&pri[i]<=n;i++)
    {
        ans+=getans(pri[i]);
    }
    cout<<ans<<"\n";
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    ///int T;cin>>T;while(T--)
        work();
    return 0;
}

你可能感兴趣的:(数学)