D - ABC Conjecture Gym - 102798D

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D - ABC Conjecture Gym - 102798D相关的知识,希望对你有一定的参考价值。

D - ABC Conjecture Gym - 102798D

题意:

规定rad(n)=n的所有质因子的乘积
给你一个c,问能否构造a和b使得a+b=c且rad(abc)<c

题解:

先说结论,如果c可以拆分出两个一样的质因子,则能构造a和b
即 n=p1a1 * p2a2 . . .*pnan,
a1到an有一个>=2即可
为什么?
首先如果a1到an都是1,那rad©=c,那么rad(abc)不可能小于c
如果a1到an存在一个>=2,怎么能够说明rad(abc)<c?看下图
在这里插入图片描述
看本题,1<=c<=1e18
线性筛可以晒出1e7以内,那么也就是可以解决[1,1e14]以内的c,那1e14到1e18之间如何解决?
我们想c = P n *x,n>=2
P为[1e14,1e18]以内的素数,那n只能是2,不然c就超范围了,而x最大也才到1e4,所有我们可以将c先除x,然后看(int)sqrt(c/x) 的平方是否等于c/x,相当于反向验证了是否存在P
详细看代码:

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e7;
int prime[maxn+1];
bool vis[maxn];
void getprime()
{
	vis[1]=1;
	for(int i=2;i<=maxn;i++)
	{
		if(!vis[i])prime[++prime[0]]=i;
		for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++)
		{
			vis[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main()
{
	getprime();
	int t;
	cin>>t;
	while(t--)
	{
		ll x;
		cin>>x;
		bool f=0;
		for(int j=1;j<=prime[0];j++)
		{
			if(x%(prime[j]*prime[j])==0)
			{
				f=1;
				break;
			}
			else if(x==1)
			{
				f=0;
				break;
			}
			else if(x%prime[j]==0)x/=prime[j];
		}
		if(f==1)cout<<"yes"<<endl;
		else if(x==1)cout<<"no"<<endl;
		else 
		{
			ll w=sqrt(1.0*x);
			if(w*w==x)cout<<"yes"<<endl;
			else cout<<"no"<<endl;
		}
	}
	return 0;
}
/*
54
1000000007
*/

以上是关于D - ABC Conjecture Gym - 102798D的主要内容,如果未能解决你的问题,请参考以下文章

cf C.Collatz Conjecture

Gym 101102D---Rectangles(单调栈)

Gym - 100989D-Cafeteria (B)

[POJ2262] Goldbach’s Conjecture

Gym 100989 D

Collatz Conjecture(BAPC2017)