题面
求
其中,
题解
完全不会莫比乌斯反演了。
先来推式子
设
所以
所以原式可以变为
又有
所以
所以所求变为
老套路了,令
后面这个玩意怎么算呢??
迷茫啊。。。。
考虑枚举的每一个
因为
假设确定了选择某个质因数
那么所有比它低的幂次都可以随意选或者不选,
一共是
这样的前提是存在比他低的次幂,也就意味着所有的幂次不全相等。
假设全部相等的时候?
也就是
其他情况下
先假设所有情况下
显然最终的和也是
但是有一种情况下为
因此贡献是
这样就可以算出后面那一坨东西的值了。
至于怎么线性筛?
额外记录每个数出去最小质因子后的数
以及最小质因子的幂次
这样就可以通过
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 10000000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
bool zs[MAX+1];
int pri[MAX+1],tot,g[MAX+1],lst[MAX+1],fp[MAX+1];
void pre()
{
for(int i=2;i<=MAX;++i)
{
if(!zs[i])pri[++tot]=i,lst[i]=g[i]=fp[i]=1;
for(int j=1;j<=tot&&i*pri[j]<=MAX;++j)
{
int x=i*pri[j];
zs[x]=true;
if(i%pri[j]==0)
{
lst[x]=lst[i];
fp[x]=fp[i]+1;
if(lst[x]==1)g[x]=1;
else g[x]=(fp[lst[x]]==fp[x]?-g[lst[x]]:0);
break;
}
lst[x]=i;fp[x]=1;g[x]=(fp[i]==1?-g[i]:0);
}
}
for(int i=1;i<=MAX;++i)g[i]+=g[i-1];
}
int main()
{
pre();
int T=read();
while(T--)
{
int a=read(),b=read();
if(a>b)swap(a,b);
ll ans=0;
for(int i=1,j;i<=a;i=j+1)
{
j=min(a/(a/i),b/(b/i));
ans+=1ll*(a/i)*(b/i)*(g[j]-g[i-1]);
}
printf("%lld\n",ans);
}
return 0;
}