(蓝桥真题)数的拆分(数论)

文章讨论了一个数论问题,即判断一个数是否能表示为两个数的幂次之和。通过质因子分解和翡蜀定理,证明了对于质因子不超过4000的情况,总能找到非负整数解。同时,对于质因子大于4000的数,只需检查其是否为平方数或立方数。代码实现中,首先初始化质数表,然后通过判断质因子的个数和检查数的平方、立方性质来得出结论。
摘要由CSDN通过智能技术生成

样例输入: 

7
2
6
12
4
8
24
72

样例输出:

no
no
no
yes
yes
no
yes

分析:由质因子分解定理我们可以知道,任意一个数x都可以唯一地分解为:

x=p1^a1 * p2^a2 * …… * pn^an

那么问我们一个数x能否表示为x1^y1 * x2^y2就等价于问我们是否存在一个数对(k1,k2)(k1,k2>=2或者等于0)使得对于任意的ai都可以表示为k1*u+k2*v=ai,有一个显然的条件是当ai=1时那么显然是不存在的。那么我们就开始讨论ai>1时是否一定存在满足题意的数对呢?答案是yes,我们如果令k1=2,k2=3,那么就是要讨论是否对于所有的ai>=2均满足2u+3v=ai有非负整数解,这个是显然的,根据翡蜀定理可以知道2*u+3*v=gcd(2,3)有解,那么gcd(2,3)|ai,所以显然是有非负整数解的。而且我们还可以直接表示出来:

对于ai%3=0,令u=0,v=ai/3

对于ai%3=1,令u=2,v=(ai-4)/3

对于ai%3=2,令u=1,v=(ai-2)/3

那么问题到这基本上就算是解决了,我们只需要判断一下ai是否大于等于2即可。

如果质因子大于4000,那么4000^2 * 4000^3>1e18,所以对于质因子大于4000的情况我们只需要判断一下该数是不是平方或者立方即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=4e3+10;
int prime[N],tt;
bool vis[N];
void init()
{
	for(int i=2;i<N;i++)
	{
		if(!vis[i]) prime[++tt]=i;
		for(int j=1;j<=tt&&i*prime[j]<N;j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0) break;
		}
	}
}
bool check(long long x)//判断x是否为平方数或者立方数
{
	long long l=1,r=1e9;
	while(l<r)
	{
		long long mid=l+r>>1;
		if(mid*mid>=x) r=mid;
		else l=mid+1;
	} 
	if(l*l==x) return true;
	l=1,r=1e6;
	while(l<r)
	{
		long long mid=l+r>>1;
		if(mid*mid*mid>=x) r=mid;
		else l=mid+1;
	} 
	if(l*l*l==x) return true;
	return false;
}
int main()
{
	init();
	int T;
	cin>>T;
	while(T--)
	{
		bool flag=true;
		long long x;
		scanf("%lld",&x);
		for(int i=1;i<=tt;i++)
		{
			int cnt=0;
			while(x%prime[i]==0)
			{
				x/=prime[i];
				cnt++;
			}
			if(cnt==1)
			{
				flag=false;
				break;
			}
		}
		if(x!=1&&!check(x)) flag=false;
		if(flag) puts("yes");
		else puts("no");
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值