Bubble Cup13-K. Lonely Numbers-小清新数论
link:https://codeforces.com/contest/1423/problem/K
题意:对两个不同正整数 \(a,b\) ,称他们是朋友,当且仅当 \(\gcd(a,b),\frac{a}{\gcd(a,b)},\frac{b}{\gcd(a,b)}\) 作为边长可以构成三角形。
在 \(\{1,\dots,n\}\) 中,称一个数是孤独的,若其和任一数都不是朋友,问 \(1\) 到 \(n\) 中有多少个数是孤独的。
\(T\leq 10^6,n\leq 10^6\).
打表找规律就不说了,没什么意思。
这题的样例应该来说很有启发性,对于 \(n=5\) 的情况, \(1,3,5\) 是孤独的,而 \(n=10\) 的时候,变成 \(1,5,7\),原本的 \(3\) 不再孤独,因为 \(3\) 和 \(9\) 可以凑成一对,得到 \(3,1,3\) 可以构成三角形。
假设某个数是合数 \(x=p\cdot q\) ,并且我们让\(p,q>1\) ,考虑 \(y=p\cdot (q-1)\),因为 \(\gcd(q,q-1)=1\),所以 \(\gcd(x,y)=p\),得到三个数 \(p,q,q-1\),这么分析好像看不出什么,但我们总是可以强制让 \(p\) 是最小质因子,因此 \(p\leq q\),那么 \(q+(q-1)>p\),并且 \(p+q>q-1\),\(p+(q-1)>1+(q-1)=q\),所以合数总是不孤独的。
对于某个素数 \(p\),其他任何数和其取 \(\gcd\),要么为 \(p\),要么为 \(1\):
- 假设 \(\gcd(x,p)=1\),则得三数为 \(1,p,x\),若 \(x\leq p-1\),则 \(x+1\leq p\),若 \(x\geq p+1\),则 \(1+p\leq x\),此时都不行。
- 反之,如果 \(x=k\cdot p\),则得到三数为 \(p,1,k\),其中 \(k\geq 2\),我们希望满足 \(1+k> p\),那么 \(k\geq p\),因此 \(x\geq p^2\).
因此得到结论:某数 \(p\) 是孤独的,当且仅当 \(p\) 是素数,且 \(p^2\leq n\),因此一个素数 \(p\) 不孤独,当且仅当 \(p^2>n\).
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N=1e6+5;
int pri[N],tot,s[N];
bool not_pri[N];
int main(){
fastio;
rep(i,2,N-5){
if(!not_pri[i])pri[++tot]=i;
for(int j=1;j<=tot&&i*pri[j]<=N-5;j++){
not_pri[i*pri[j]]=true;
if(i%pri[j]==0)break;
}
}
rep(i,2,N-5)s[i]=s[i-1]+(!not_pri[i]);
int tc;cin>>tc;
while(tc--){
int n;cin>>n;
cout<<s[n]-s[(int)sqrt(n)]+1<<endl;
}
return 0;
}