玲珑杯 #round 9 1084 - Check-in Problem


点击打开链接


这个题好纠结啊。

开始根本没有理解题意,最后才发现,p一定是质数,,,,,这个当时一直没发现。

已知n 和p的范围,

由素数算数基本定理得  n 能拆分程 x个素数之积。

n的因子个数为(a1+1)(a2+1).。。。

已知p为质数,所以  如果n为p的奇异数,则一定满足 n开p-1次方 一定是一个素数。

所以  当p>3 时, 情况不多,打表就行。

             p=3时, 直接对n开方,在判断是否是素数就行。



#include <bits/stdc++.h>
typedef long long LL;
const int maxn = 31623, maxm = 17, maxp = 61;//sqrt(10^9) , 60以内素数个数 , ln(10^18)
const LL maxv = (LL)1e18,maxq=(LL)1e9;
int tot, pr[maxn], d[maxn], sz[maxm];
LL pp[maxm][maxn];
bool isprime(int x){ //判素
	if(x<2) return 0;
	if(x<maxn) return d[x] == x;
	for(int i=0;i<tot&&pr[i]*pr[i]<=x;++i)
		if(x%pr[i]==0) return 0;
	return 1;
}
int main(){
    tot=0;
	for(int i=2; i<maxn; ++i){//快速线性筛法求素数
		if(!d[i])
			pr[tot++] = d[i] = i;
		for(int j=0,k;(k=i*pr[j])<maxn;++j){
			d[k]=pr[j];
			if(!(d[i]%pr[j]))
				break;
		}
	}
	for(int i=2;i<maxm;++i){//打表
		for(int j=0;j<tot;++j){
			int rem=pr[i]-1;
			LL val=1,lim=maxv/pr[j];
            for( ;rem&&val<=lim;--rem,val*=pr[j]);
			if(rem) break;
			pp[i][sz[i]++] = val;
		}
	}
	int t;
	LL n, p;
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld",&n,&p);
		if(p>=maxp||d[p]!=p){
			puts("NO");
			continue;
		}
		if(p==3){
			LL val=(LL)sqrt(n);
			puts(val*val==n&&isprime(val)?"YES":"NO");
			continue;
		}
		for(int i=2;i<maxm;++i)
			if(pr[i]==p){
				puts(*std::lower_bound(pp[i],pp[i]+sz[i],n)==n?"YES":"NO");
				break;
			}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值