3309: DZY Loves Math 莫比乌斯反演

F(i) 表示 i 所含质因子最大幂指数, f(i) 表示 gcd(x,y)=i 的数对 (x,y) 的数量,然后莫比乌斯反演得到下式:

Ans=T=1nnTmTdTF(d)μ(Td)

G(T)=dTF(d)μ(Td) ,然后我们大力讨论一下。
首先设 T=Px11×Px22×..×Pxkk,d==Py11×Py22×..×Pykk
要使 μ(Td)0 ,必须满足 yi=xi 或者 yi=xi1
a=Max1ik(xi) ,则 F(d)=a a1
假设 T 中一共有 q 个质因子的指数为 a

一、当 q=k 时,
f(d)=a

f(d)=af(d)μ(Td)=a×f(d)=aμ(Td)=a×i=1k(1)kiCik=a×(1)k+1

f(d)=a1
f(d)=a1f(d)μ(Td)=(a1)×f(d)=a1μ(Td)=(a1)×(1)k

所以当 q=k 时, G(T)=a×(1)k+1+(a1)×(1)k=(1)k+1
二、当 q<k
f(d)=a
f(d)=af(d)μ(Td)=a×f(d)=aμ(Td)=a×i=1q(1)qiCiq×j=0kq(1)jCjkq=0

f(d)=a1
f(d)=a1f(d)μ(Td)=(a1)×f(d)=a1μ(Td)=(a1)×(1)q×j=0kq(1)jCjkq=0

所以当 q<k 时, G(T)=0
知道这些,我们可以线筛的时候记录一下最小质因子出现的次数和除去最小质因子 px11 后的数,然后判断幂指数是否相等。

#include
#include
#define ll long long 
#define MAXN 10000005
using namespace std;
int prime[MAXN],t[MAXN],last[MAXN];
ll g[MAXN];
bool flag[MAXN];
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void prepare()
{
    for (int i=2;iif (!flag[i]) prime[++prime[0]]=i,last[i]=t[i]=g[i]=1;
        for (int j=1;j<=prime[0]&&i*prime[j]*prime[j]]=1;
            if (i%prime[j]==0)
            {
                last[i*prime[j]]=last[i];
                t[i*prime[j]]=t[i]+1;
                if (last[i*prime[j]]==1) g[i*prime[j]]=1;
                else g[i*prime[j]]=(t[last[i*prime[j]]]==t[i*prime[j]]?-g[last[i*prime[j]]]:0);
                break;
            }
            last[i*prime[j]]=i;
            t[i*prime[j]]=1;
            g[i*prime[j]]=(t[i]==1?-g[i]:0);
        }
    }
    for (int i=1;i1];
}
inline ll solve(ll n,ll m)
{
    ll ans=0;
    for (int i=1,pos;i<=n;i=pos+1)
    {
        pos=min(n/(n/i),m/(m/i));
        ans+=(g[pos]-g[i-1])*(n/i)*(m/i);
    }
    return ans;
}
int main()
{
    prepare();
    int testcase=read();
    while (testcase--)
    {
        ll n=read(),m=read();
        if (n>m) swap(n,m);
        printf("%lld\n",solve(n,m));
    }
    return 0;
}

你可能感兴趣的:(My,Code)