当前位置: 代码迷 >> 综合 >> LightOJ - 1220 Mysterious Bacteria(唯一分解定理)
  详细解决方案

LightOJ - 1220 Mysterious Bacteria(唯一分解定理)

热度:27   发布时间:2023-12-09 20:15:31.0

链接:LightOJ - 1220 Mysterious Bacteria

题意:

给出 x x x,求最大的整数 e e e满足:存在整数 y y y,使得 x = y e x=y^e x=ye

x x x是一个32位有符号整数,且保证 ∣ x ∣ ≥ 2 |x|\ge2 x2



分析:

先假设 x x x为正,根据唯一分解定理,得到

x = p 1 a 1 ? p 2 a 2 ? p n a n x=p_1^{a_1}\cdot p_2^{a_2}\cdots p_n^{a_n} x=p1a1???p2a2???pnan??

存在整数 y y y,使得 x = y e x=y^e x=ye,即 x 1 e = y x^{\frac{1}{e}}=y xe1?=y,即

p 1 a 1 e ? p 2 a 2 e ? p n a n e = y p_1^{\frac{a_1}{e}}\cdot p_2^{\frac{a_2}{e}}\cdots p_n^{\frac{a_n}{e}}=y p1ea1????p2ea2????pnean???=y

上式要等于一个整数,那么一定有 e ∣ a i e|a_i eai?,所以最大的 e e e就等于
e m a x = gcd ? ( a 1 , a 2 , … , a n ) e_{max}=\gcd(a_1,a_2,\dots,a_n) emax?=gcd(a1?,a2?,,an?)


x x x为负数,则可以转化为正的先,求得 e m a x e_{max} emax?,但是对于负数 e m a x e_{max} emax?必须为奇数,所以应当让 e m a x e_{max} emax?不断除以 2 2 2,直至变成奇数。



以下代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e5+50;
int prime[10000],tot;
bool vis[maxn];
void get_prime()
{
    tot=0;for(int i=2;i<=maxn;i++){
    if(!vis[i])prime[++tot]=i;for(int j=1;j<=tot&&i*prime[j]<=maxn;j++){
    vis[i*prime[j]]=true;if(i%prime[j]==0)break;}}
}
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
LL x;
int ans;
bool neg;
int main()
{
    get_prime();int T,kase=0;scanf("%d",&T);while(T--){
    scanf("%lld",&x);if(x<0){
    x=-x;neg=true;}elseneg=false;ans=0;for(int i=1;i<=tot&&prime[i]*prime[i]<=x;i++){
    if(x%(1LL*prime[i])==0){
    int a=0;while(x%(1LL*prime[i])==0){
    a++;x/=1LL*prime[i];}ans=gcd(ans,a);}}if(x>1)ans=gcd(ans,1);if(neg){
    while(!(ans&1))ans>>=1;}printf("Case %d: %d\n",++kase,ans);}return 0;
}
  相关解决方案