zoukankan      html  css  js  c++  java
  • POJ 3641 素数打表+快速幂 简单题

    给出2个数,p和a,2<p<=1e9,1<a<p

    若p满足下面2个条件,输出yes,否则输出no

    1.p不是素数

    2.有a^p=a(mod p)

    先判断第一个条件:

    本来想用一个数组is_prime[i]表示i是不是素数的,明显,这里p太大,数组开不下

    若p不是素数的话,

    则p必有p=b*c,其中b<=c,

    则(sqrt(p))^2=b*c,则b<=sqrt(p)<=10^4.5<10^5

    所以若在10^5内存在数b满足b<p&&p%b==0,说明p不是素数

    进一步,只要验证10^5存在素数b1满足b1<p&&p%b1==0,说明p不是素数,即满足第一个条件

    所以只要把10^5内的所有素数找出来,放在数组prime里面,对于p,遍历一边即可,注意:prime[i]>=p时,要break

    若满足了第一个条件,验证第二个条件,快速幂即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 
     5 using namespace std;
     6 
     7 #define LL long long
     8 
     9 const int maxn=1e5;
    10 bool is_prime[maxn];
    11 int prime[maxn>>1];
    12 
    13 int init_prime()
    14 {
    15     int i;
    16     int tot=1;
    17     int e=(int)(sqrt(0.0+maxn)+1);
    18     memset(is_prime,true,sizeof is_prime);
    19     is_prime[1]=false;
    20     is_prime[2]=true;
    21     prime[tot++]=2;
    22     for(i=4;i<maxn;i+=2)
    23         is_prime[i]=false;
    24     for(i=3;i<e;i+=2)
    25     {
    26         if(is_prime[i])
    27         {
    28             prime[tot++]=i;
    29             int s;
    30             for(int j=i*i,s=2*i;j<maxn;j+=s)
    31                 is_prime[j]=false;
    32         }
    33     }
    34     for(;i<maxn;i+=2)
    35     {
    36         if(is_prime[i])
    37             prime[tot++]=i;
    38     }
    39     return tot;
    40 }
    41 
    42 LL quick_pow(LL a,LL p)
    43 {
    44     LL mod=p;
    45     LL ret=1;
    46     while(p>0)
    47     {
    48         if(p&1)
    49             ret=ret*a%mod;
    50         a=a*a%mod;
    51         p>>=1;
    52     }
    53     return ret;
    54 }
    55 
    56 void solve(int tot,LL p,LL a)
    57 {
    58     bool flag=false;
    59     for(int i=1;i<tot;i++)
    60     {
    61         if(prime[i]>=p)
    62             break;
    63         if(p%prime[i]==0)
    64         {
    65             flag=true;
    66             break;
    67         }
    68     }
    69     if(!flag)
    70     {
    71         printf("no
    ");
    72         return ;
    73     }
    74     LL ret=quick_pow(a,p);
    75     if(ret%p==a%p)
    76     {
    77         printf("yes
    ");
    78     }
    79     else
    80     {
    81         printf("no
    ");
    82     }
    83     return ;
    84 }
    85 
    86 int main()
    87 {
    88     LL p,a;
    89     int tot=init_prime();
    90     while(scanf("%lld%lld",&p,&a))
    91     {
    92         if(!p&&!a)
    93             break;
    94         solve(tot,p,a);
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    高盛、沃尔玛 题做出来还挂了的吐槽
    amazon师兄debrief
    到所有人家距离之和最短的中点 296. Best Meeting Point
    问问题没人回答的情况怎么办终于有解了
    找名人 277. Find the Celebrity
    数组生存游戏 289. Game of Life
    547. Number of Provinces 省份数量
    428. Serialize and Deserialize Nary Tree 序列化、反序列化n叉树
    alias别名简介和使用
    面试官:线程池执行过程中遇到异常会发生什么,怎样处理? Vincent
  • 原文地址:https://www.cnblogs.com/-maybe/p/4695775.html
Copyright © 2011-2022 走看看