SPOJ PON - Prime or Not

题目链接http://www.spoj.com/problems/PON/

题目大意:判断N是不是素数,N<264-1.

解题思路:需要用到拉宾-米勒素性判定。

(选自数论书籍)合数的拉宾-米勒测试:设n是奇素数,记n-1=2kq,q为奇数。对不被n整除的某个a,如果下述两个条件都成立,则n是合数。

  a): aq !≡ 1 (mod n),   即a的q次方不与1模n同余

  b): 对所有i = 0,1,2,……,k-1, a2^i * q !≡ -1 (mod n)

所以可以打出100个素数表然后迭代判定。其中需要用的:快速幂取模,大数乘取模。

代码:

 1 const int maxn = 1e5 + 10;
 2 VI primes;
 3 bool vis[maxn];
 4
 5 ll mul_mod(ll a, ll b, ll m){
 6     ll ans = 0, base = a;
 7     while(b){
 8         if(b & 1) ans = (ans + base) % m;
 9         base %= m;
10         base = base * 2 % m;
11         b >>= 1;
12     }
13     return ans;
14 }
15 ll pow_mod(ll a, ll b, ll m){
16     ll ans = 1, base = a % m;
17     while(b){
18         if(b & 1) ans = mul_mod(ans, base, m);
19         base %= m;
20         base = mul_mod(base, base, m);
21         b >>= 1;
22     }
23     return ans % m;
24 }
25 void dowork(){
26     memset(vis, 0, sizeof(vis));
27     for(int i = 2; i < maxn / 2; i++)
28         for(int j = i * 2; j > 0 && j < maxn; j += i)
29             vis[j] = 1;
30     for(int i = 2; i < 1e5; i++)
31         if(!vis[i]) primes.push_back(i);
32 }
33 bool check(ll x){
34     if(x == 2) return true;
35     if(x % 2 == 0) return false;
36     ll q = x - 1;
37     int k = 0;
38     while(!(q & 1)){
39         k++; q >>= 1;
40     }
41     bool flag = true;
42     for(int i = 0; i < 100; i++){
43         ll a = primes[i];
44         if(a == x) return true;
45         if(pow_mod(a, q, x) == 1)
46             continue;
47         bool none = true;
48         for(int j = 0; j < k; j++){
49             ll qi = 1 << j;
50             ll tmp = pow_mod(a, qi * q, x);
51             if(tmp == x - 1){
52                 none = false;
53                 break;
54             }
55             else if(tmp == 1)
56                 break;
57         }
58         if(none) {
59             flag = false;
60             break;
61         }
62     }
63     return flag;
64 }
65 int main(){
66     dowork();
67     int t;
68     scanf("%d", &t);
69     while(t--){
70         ll n;
71         scanf("%lld", &n);
72         if(check(n)) puts("YES");
73         else puts("NO");
74     }
75 }

题目:

PON - Prime or Not

#cryptography #prime-numbers-1 #primality-test

Given the number, you are to answer the question: "Is it prime?"

Solutions to this problem can be submitted in C, C++, Pascal, Perl, Python, Ruby, Lisp, Hask, Ocaml, Prolog, Whitespace, Brainf**k and Intercal only.

Input

t – the number of test cases, then t test cases follows. [t <= 500]
Each line contains one integer: N [2 <= N <= 2^63-1]

Output

For each test case output string "YES" if given number is prime and "NO" otherwise.

Example

Input:
5
2
3
4
5
6

Output:
YES
YES
NO
YES
NO

Submit solution!

时间: 2024-10-05 09:22:06

SPOJ PON - Prime or Not的相关文章

Spoj PRIME1 - Prime Generator

题意翻译 求给定的两个数之间的素数 Translated by @kaiming 题目描述 Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers! 输入输出格式 输入格式: The input begins with the number t of test cas

The Inclusion-Exclusion Principle

The Inclusion-Exclusion Principle The inclusion-exclusion principle is an important combinatorial way to compute the size of a set or the probability of complex events. It relates the sizes of individual sets with their union. Statement The verbal fo

SPOJ Prime or Not - 快速乘 - 快速幂

Given the number, you are to answer the question: "Is it prime?" Solutions to this problem can be submitted in C, C++, Pascal, Perl, Python, Ruby, Lisp, Hask, Ocaml, Prolog, Whitespace, Brainf**k and Intercal only. Input t – the number of test c

SPOJ Problem 2: Prime Generator

嗯..在SPOJ上刷的第二题. 一开始不知道哪错了,后来发现i出现了两遍.. 因为m<10^9,所以用素数筛筛32000以内的数,开一个4000的数组存储就行.然后再从n开始用素数筛,总之效率还行. 代码如下: //0.01s 3.2M #include<cstdio> #include<cstring> #include<cmath> int n,i,j,t,m,k,tot; int a[100005],b[4000]; int prime[40000]; in

素数筛法--SPOJ Problem 2 Prime Generator

质数(prime number)又称素数,除了1和它本身外,不能整除以其他自然数,换句话说就是该数除了1和它本身以外不再有其他的因数:否则称为合数.最小的质数是2. 要判断一个整数N是不是质数很简单,看它是否能被2到sqrt(N)之间的整数整除即可. def isPrime(n): if n%2==0: return False for i in xrange(3,int(math.sqrt(n)+1),2): if n%i==0: return False return True 不过要找出1

SPOJ CZ_PROB1 - Summing to a Square Prime

题目链接:http://www.spoj.com/problems/CZ_PROB1/ 题目大意:Sp2 是所有素数中能够被分解为两个数的平方和的素数的集合.P(a,b)指的是在a的划分中,最大元素不超过b的划分的个数(就是那个经典整数划分动态规划题).给你个n,k,问P(sp2[n],k)是多少. 0<T<501 0<n<501 1<SP2(n)<7994 0<k<4 解题思路:既然题中已经给出sp2集合的限制,那么sp2直接打表,按照经典动态规划算法计算

SPOJ Python Day2: Prime Generator

2. Prime Generator 任务很简单,生成m到n之间的所有质数.一个比较常见的思路是: 自然数$1, 2, -, N$中的最大的质因子要小于$\sqrt{N}$.所以用m到n中的每一个数去试除1到$\sqrt{n}$中的所有数.能整除就是合数,全不能整除就是质数. 但是这么做会超时.. 一般生成质数有一个常用的算法:筛法 http://zh.wikipedia.org/wiki/%E5%9F%83%E6%8B%89%E6%89%98%E6%96%AF%E7%89%B9%E5%B0%B

Prime Generator(spoj)

原题: Prime Generator Problem code: PRIME1 Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers! Input The input begins with the number t of test cases in a sing

BZOJ 2226: [Spoj 5971] LCMSum( 数论 )

∑lcm(i,n) = ∑ i*n/(i,n) = ∑d|n∑(x,n)=d x*n/d = ∑d|n∑(t,n/d)=1t*n = n∑d|nf(d). f(d)表示1~d中与d互质的数的和, 即f(d) = d*φ(d)/2(d>=2). 然后O(n)筛φ, 每次询问暴力算即可...最大是100w,sqrt(100w)=1000内的质数是168个, 所以复杂度是O(n + T*168), 可以AC  ----------------------------------------------