传送门:
题意:问有多少对(i,j)满足i<=n&&j<=n&&i*j是一个平方数
分析:打表然后OEIS。考虑枚举i,再加上j可能的个数。对于一个i,如果他是平方数,那么j的取值也必须是平方数;如果i不是平方数,那么找到大于i的最小平方数,也就是把i的质因数中出现奇数次的质因子补上,我们把vx[i]定义为i的质因数中出现奇数次的质因子的乘积,也就是j最小的取值。之后只需加上平方数的个数即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
vector<int>v[N];
int vx[N];
void init()//O(能过1e6)
{
for(int i=2;i<N;i++)//枚举质因数
{
if(v[i].size()==0)//质数
{
for(int j=i;j<N;j+=i)
{
int temp=j;
while(temp%i==0)
{
v[j].push_back(i);
temp/=i;
}
}
}
}
}
signed main()
{
init();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
vx[i]=1;
for(int j=0;j<v[i].size();j++)
{
if(v[i][j]==v[i][j+1]&&j+1<v[i].size())
{
j++;
}
else vx[i]*=v[i][j];
}
}
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=sqrt(n/vx[i]);
}
cout<<sum<<endl;
}