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的主要内容,如果未能解决你的问题,请参考以下文章