LightOJ1220

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1220

题目大意:

  给你一个 x,请求出一个最大的 p 使得 np = x(n为任意整数)。注意,x 有可能是负数。

解题思路:

  算术基本定理。

  求出 |x| 的唯一分解式,然后求各项指数的最大公因数。如果 x<0,那么还要事先将分解式的每一项的指数都转化成奇数(负数的偶数次方就变成正数了嘛)。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn = 1e5;
 8 bool not_prime[maxn];
 9 int prime[maxn];
10 int cnt;
11 void init(){
12     cnt=0;
13     not_prime[0]=not_prime[1]=true;
14     for(ll i=2;i<maxn;i++){
15         if(!not_prime[i]){
16             prime[cnt++]=i;
17             for(ll j=i*i;j<maxn;j+=i)
18                 not_prime[j]=true;
19         }
20     }
21 }
22 int gcd(int a,int b){
23     if(b==0)    return a;
24     return gcd(b,a%b);
25 }
26 int ind[maxn];
27 int solve(ll x){
28     bool fu=false;
29     if(x<0){
30         fu=true;
31         x=-x;
32     }
33     int tmp=0;
34     for(int i=0;i<cnt;i++){
35         if(x%prime[i]==0){
36             ind[tmp]=1; x/=prime[i];
37             while(x%prime[i]==0){
38                 ind[tmp]++;
39                 x/=prime[i];
40             }
41             tmp++;
42         }
43     }
44     if(x>1)  ind[tmp++]=1;
45     if(fu){
46         int ret=ind[0];
47         while(ret%2==0) ret/=2;
48         if(ret==1)  return 1;
49         for(int i=1;i<tmp;i++){
50             while(ind[i]%2==0)  ind[i]/=2;
51             ret=gcd(ret,ind[i]);
52             if(ret==1)  return 1;
53         }
54         return ret;
55     }
56     else{
57         int ret=ind[0];
58         if(ret==1)  return 1;
59         for(int i=1;i<tmp;i++){
60             ret=gcd(ret,ind[i]);
61             if(ret==1)return 1;
62         }
63         return ret;
64     }
65 }
66 int main(){
67     init();
68     ll x;
69     int T;
70     scanf("%d",&T);
71     for(int t=1;t<=T;t++){
72         scanf("%lld",&x);
73         printf("Case %d: %d\n",t,solve(x));
74     }
75     return 0;
76 }

 

posted @ 2017-10-26 17:06  Blogggggg  阅读(163)  评论(0)    收藏  举报