bzoj3309: DZY Loves Math

9 篇文章 0 订阅

这显然要用莫比乌斯反演:

Ans=ai=1bj=1f(gcd(i,j))=df(d)adi=1bdj=1[gcd(i,j)=1]=df(d)adi=1bdj=1p|Tμ(p)=df(d)p|Tμ(p)adpbdp=min(a,b)T=1aTbT×p|Tf(p)μ(Tp)

g(T)=p|Tf(p)μ(Tp)T=p1a1p2a2pnan,p=p1b1p2b2pnbn

要使 μ(T/p)0 aibi=01

a1=a2=...an 则:所有 bi=ai1 此时f为a-1,或存在 bi=ai 此时f为a,在这种情况下μ值为1和-1的情况差一,和为a。

若存在 aiaj 则只有最大的a能影响答案,对每种情况,其他a的μ和为零。

差不多就是这样吧,可能不太对。。。//真弱←__←

#include<iostream>
#include<cstdio>
#define N 10000005
#define ll long long
using namespace std;
int T,a,b;ll Ans;
int p[1000005],cnt,vis[N],M[N],Mp[N],g[N];
int main()
{
    for (int i=2;i<=10000000;i++)//M[i]表示i的最小质因子k的次数,Mp[i]表示k^M[i]
    {
        if (!vis[i]) p[++cnt]=Mp[i]=i,g[i]=M[i]=1;//i是质数
        for (int j=1;j<=cnt&&i*p[j]<=10000000;j++)
        {
            int t=i*p[j];vis[t]=1;
            if (i%p[j]==0)//i中存在p[j],p[j]也是i的最小质因子
            {
                M[t]=M[i]+1;
                Mp[t]=Mp[i]*p[j];
                int k=i/Mp[i];//k为i中除p[j]外的数
                if (k==1) g[t]=1;else g[t]=(M[k]==M[t])?-g[k]:0;
                break;
            }
            M[t]=1;//i中没有p[j]
            Mp[t]=p[j];
            g[t]=(M[i]==1)?-g[i]:0;
        }
    }
    for (int i=1;i<=10000000;i++) g[i]+=g[i-1];//前缀和
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&a,&b);
        if (a>b) swap(a,b);
        Ans=0;
        for (int i=1,j;i<=a;i=j+1)//分块
        {
            j=min(a/(a/i),b/(b/i));
            Ans+=(ll)(a/i)*(b/i)*(g[j]-g[i-1]);
        }
        printf("%lld\n",Ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值