GCD Guessing Game
https://www.luogu.com.cn/problem/UVA1521
$ gcd=1 $ 的话,排除了x中所有因子及其倍数(除了1)
$ gcd>1 $的话,范围变成了gcd的整数倍
显然,下面那个缩小得更快,但题目问的是“ 最坏情况下 ”,所以是用上面那个,显然$ p=1 $,肯定 \(gcd=1\),注意你“ 使用最优策略 ”,所以接下来肯定不会继续猜1 ,那么你猜的最坏情况就是一堆质数,当然了,不能一个一个得猜,因为你“ 使用最优策略 ”,所以你每次猜一个大质数顺便带几个小质数(能带几个是几个)。筛一下,双指针扫就行。
注意不能把几个小质数连乘起来,因为可能x是大质数的倍数,这。样“把几个小质数连乘起来:肯定不是最优的
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e4+10;
inline int read() {
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
int n,p[N],mindiv[N];
void init() {
for(int i=2;i<N;i++) {
if(!mindiv[i]) p[++p[0]]=mindiv[i]=i;
for(int j=1;j<=p[0]&&i*p[j]<N;j++) {
mindiv[i*p[j]]=p[j];
if(i%p[j]==0) break;
}
}
}
int main() {
init();
while(scanf("%d",&n)==1) {
int l=1;
int r=upper_bound(p+1,p+1+p[0],n)-p-1;
int ans=0;
while(l<=r) {
ans++;
int tmp=p[r--];
if(r<l) break;
while(l<=r&&tmp*p[l]<=n)
tmp*=p[l++];
}
printf("%d\n",ans);
}
return 0;
}