HDU 5750 Dertouzos(数论)

14 篇文章 0 订阅

传送门

题意:在小于n的范围内,找出所有最大除数为d的数。

思路:假设存在一个y满足题目条件,即y=k*d,那么我们可以分析出来 k一定为质数,而且k<=d,因为只有这样k才不能分解成两个大于1的数,如果一旦分成两个大于1的数a,b;那么a*d也是y的因子而且比d大了。既然这样的话,我们就可以通过素数筛预处理素数。

枚举每一个素数和d的乘积是否满足,那何时终止呢?(素数存入V数组

1.当v[i]*d>=n 不满足条件了,显然要终止了;

2.当v[i]是d的因子时(这个也保证了v[i]<d)此时也要终止了,但res++;

   当d不是质数时,则d可以分成两个大于1的数,一个最小质数因子和另一个数,v[i]是最小质数因子时,此时乘积的最大除数还是  d,但当v[i]再大时,v[i]就会和另一个数相乘变成一个>d的数。

   当d是质数时,那d只能分成1和d,当v[i]时d是, 乘积的最大除数还是 d,v[i]再大,那最大除数就成了v[i]了。

一点注意:噢,还有一点,就是素数筛的时候,筛选的上界并不是n(1e9),这也是一开始做这个没有注意到的,以为素数筛数组开不了。因为如果d是质数那么d*d就结束了,而且d*d要小于n,如果d不是质数,那么跑的它的最小质因子就结束了;综上,所以筛选的上界是sqrt(n),保险可以开大一点。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
int T,n,d,psize;
ll v[maxn];
bool pd[maxn+1];
void work() {
	psize=0;
	pd[0]=true;
	pd[1]=true;
	for(int i=2; i<=maxn; ++i) {
		if(!pd[i]) {
			v[psize++]=i;
			for(int j=2*i; j<=maxn; j+=i) {
				pd[j]=true;
			}
		}
	}
	
}
int main() {
	scanf("%d",&T);
	work();
	while(T--) {
		scanf("%d%d",&n,&d);
		ll res=0;
		for(int i=0;i<psize;++i){
			if(v[i]*d>=n){
				break;
			}
			res++;
			if(d%v[i]==0){
				break;	
			}
		}
		cout<<res<<endl;
	}

	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值