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\n");
72         return ;
73     }
74     LL ret=quick_pow(a,p);
75     if(ret%p==a%p)
76     {
77         printf("yes\n");
78     }
79     else
80     {
81         printf("no\n");
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 }

时间: 2024-10-11 23:19:01

POJ 3641 素数打表+快速幂 简单题的相关文章

POJ 3641 Pseudoprime numbers(快速幂)

嗯... 题目链接:http://poj.org/problem?id=3641 AC代码: 1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 inline bool is_prime(int x){ 7 if(x == 2) return 1; 8 if(x % 2 == 0) return 0; 9 for(int i = 3; i * i <= x; i += 2){ 10 if(!

poj 3641 Pseudoprime numbers 【快速幂】

Pseudoprime numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6645   Accepted: 2697 Description Fermat's theorem states that for any prime number p and for any integer a > 1, ap = a (mod p). That is, if we raise a to the pth power

poj 3070 矩阵快速幂简单题

基本运用,基本是模板题. 求fi[n].       (1,1)    *( 1  ) ( 1,0)     (  0) #include<iostream> #include<cstring> using namespace std; struct juz { int bat[3][3]; int x,y; //行 列 }; juz mutp(juz a,juz b) { juz c; c.x=a.x;c.y=b.y; memset(c.bat,0,sizeof(c.bat));

UVA10006 - Carmichael Numbers(筛选构造素数表+快速幂)

UVA10006 - Carmichael Numbers(筛选构造素数表+快速幂) 题目链接 题目大意:如果有一个合数,然后它满足任意大于1小于n的整数a, 满足a^n%n = a;这样的合数叫做Carmichael Numbers.题目给你n,然你判断是不是Carmichael Numbers. 解题思路:首先用筛选法构造素数表,判断n是否是合数,然后在用快速幂求a^2-a^(n - 1)是否满足上述的式子.快速幂的时候最好用long long ,防止相乘溢出. 代码: #include <

poj 2778 AC自动机 + 矩阵快速幂

// poj 2778 AC自动机 + 矩阵快速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自动机,确定状态之间的关系,构造出,走一步 // 能到达的状态矩阵,然后进行n次乘法,就可以得到状态间 // 走n步的方法数. // 精髓: // 1):这个ac自动机有一些特别,根节点是为空串,然而 // 每走一步的时候,如果没法走了,这时候,不一定是回到根 // 节点,因为有可能单个的字符时病毒,这样

UVA 11582 Colossal Fibonacci Numbers!(打表+快速幂)

Colossal Fibonacci Numbers! The i'th Fibonacci number f (i) is recursively defined in the following way: f (0) = 0 and f (1) = 1 f (i+2) = f (i+1) + f (i)  for every i ≥ 0 Your task is to compute some values of this sequence. Input begins with an int

POJ 3070 Fibonacci(矩阵快速幂)

题目链接 题意 : 用矩阵相乘求斐波那契数的后四位. 思路 :基本上纯矩阵快速幂. 1 //3070 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 6 using namespace std; 7 8 struct Matrix 9 { 10 int v[2][2]; 11 }; 12 int n; 13 14 Matrix matrix_mul(Matrix a,Matrix b) 1

[POJ 3150] Cellular Automaton (矩阵快速幂 + 矩阵乘法优化)

Cellular Automaton Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 3048   Accepted: 1227 Case Time Limit: 2000MS Description A cellular automaton is a collection of cells on a grid of specified shape that evolves through a number of dis

POJ 3070 Fibonacci(矩阵快速幂模板)

Description: In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … An alternative formula for the Fibonacci sequence i