CF1423K
题意:
多组询问,每次询问给出 \(n\) ,回答对于所以 \(i\in [1,n]\) ,有多少个 \(i\) 满足不存在 \(j\in [1,n]\) 使得 \(\gcd(i,j)\) ,\(\frac{j}{\gcd(i,j)}\) ,\(\frac{i}{\gcd(i,j)}\) 构成三角形 。
思路:
首先观察样例可以发现:
- 偶数一定不对答案有贡献,因为可以选择 \(i\) 和 \(i\pm2\) 使得他们的最大公约数为 \(2\) ,另外两边之差一定是 \(1\) ;
可以依照这种思路分类下去,由于奇数的情况有些复杂在最后讨论;
- 考虑某些质数 \(p\) ,那么 \(\gcd(p,j)\) 一定是 \(1\) 或 \(p\) ,\(\frac{p}{\gcd(p,j)}\) 与对应上面是 \(p\) 或 \(1\) ,\(\frac{j}{\gcd(p,j)}\) 与上面对应一定是 \(j\) 或 \(\frac{j}{p}\) ,发现不管怎么样都存在恰好 \(1\) 个 \(1\) ,所以两个不等于 \(1\) 的值必须相等,那么 \(j\gets p^2\) 即可,那么显然 \(p\leq \sqrt n\) 的质数都存在 \(j\) 满足条件;
- 现在考虑奇数的情况,质数已经证明可以,合数可以选择其最小的质因子 \(p\) ,可以构造 \(i-p\) ,\(i\) 即可;
综上,所有合数满足条件,大于 \(\sqrt n\) 的质数都不满足,\(1\) 不满足,求前缀素数个数 \(s_i\) 表示 \(1-i\) 的素数个数,答案即为 \(s_n-s_{\sqrt n}+1\)
代码:
using namespace std;
bool isp[1100005];
int q,n,arr[1100005];
signed main()
{
isp[0]=1,isp[1]=1;
for(int i=2;i<=1100000;i++)
{
if(!isp[i])
{
for(int j=i*i;j<=1100000;j+=i)
{
isp[j]=1;
}
}
}
for(int i=1;i<=1e6+5;i++)
{
arr[i]=arr[i-1]+(isp[i]==0);
}
cin>>q;
while(q--)
{
scanf("%lld",&n);
printf("%lld\n",arr[n]-arr[(int)(sqrt(n))]+1);
}
}