题意:
m*n的方格中每个格点都种了一棵树,问站在0,0点能看到多少棵树
思路:
求1~n,1~m之间gcd(x,y)=1的对数
反演的模板题
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <bitset>
#define max_ 110000
#define inf 0x3f3f3f3f
#define ll long long
#define les 1e-8
#define mod 10000007
using namespace std;
ll n,m;
int pl=0;
bool vis[max_];
int prime[max_];
int mu[max_];
int pre[max_];
void getprime()
{
mu[1]=1;
pre[1]=1;
for(int i=2;i<max_;i++)
{
if(vis[i]==false)
{
prime[++pl]=i;
mu[i]=-1;
}
for(int j=1;j<=pl&&prime[j]*i<max_;j++)
{
vis[prime[j]*i]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
{
mu[prime[j]*i]=-mu[i];
}
}
pre[i]=pre[i-1]+mu[i];
}
}
int main()
{
getprime();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
if(n>m)
swap(n,m);
int eend;
ll ans=0;
for(ll i=1;i<=n;i=eend+1)
{
eend=min(n/(n/i),m/(m/i));
ans+=(pre[eend]-pre[i-1])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
}