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;
}

posted @ 2020-10-27 19:36  ke_xin  阅读(75)  评论(0编辑  收藏  举报