Hackerrank--Prime Sum

题目链接

The problem is quite simple. You‘re given a number N and a positive integer K. Tell if N can be represented as a sum of K prime numbers (not necessarily distinct).

Input Format
The first line contains a single integer T, denoting the number of test cases. 
Each of the next T lines contains two positive integers, N & K, separated by a single space.

Output Format
For every test case, output "Yes" or "No" (without quotes).

Constraints
1 <= T <= 5000 
1 <= N <= 1012 
1 <= K <= 1012

Sample Input

2
10 2
1 6

Sample Output

Yes
No

Explanation

In the first case, 10 can be written as 5 + 5, and 5 is a prime number. In the second case, 1 cannot be represented as a sum of prime numbers, because there are no prime numbers less than 1.

题意:给两个正整数n和k,问能否将n分解为k个素数的和(可以出现相同的)。

思路:本题涉及的知识点有哥德巴赫猜想(任何大于2的偶数都可以拆分成两个素数的和),

还有Miller-Rabin素数测试,一般使用的素数测试是O(sqrt(n))复杂度的,无法满足大整数的要求。

费马小定理: 如果p是一个素数,且(0<a<p),则

例如,67是一个素数,则2^66 mod 67=1.

利用费马小定理,对于给定的整数n,可以设计一个素数判定算法.通过计算d=2^(n-1) mod n 来判定整数n的素性.当d≠1时,n肯定不是素数;当d=1时,n则很可能是素数,但也存在合数n,使得 .例如,满足此条件的最小合数是n=341.为了提高测试的准确性,我们可以随机地选取整数1<a<n-1,然后用条件 来判定整数n的素性.例如对于n=341,取a=3时,有 ,故可判定n不是素数.

费马小定理毕竟只是素数判定的一个必要条件.满足费马小定理条件的整数n未必全是素数.有些合数也满足费马小定理的条件.这些合数被称作Carmichael数,前3个Carmichael数是561,1105,1729. Carmichael数是非常少的.在1~100000000范围内的整数中,只有255个Carmichael数.

利用下面的二次探测定理可以对上面的素数判定算法作进一步改进,以避免将Carmichael数当作素数.

二次探测定理  如果p是一个素数,且0<x<p,则方程x*x≡1(mod p)的解为x=1,p-1.

事实上, x*x≡1(mod p)等价于 x*x-1≡0(mod p).由此可知;

(x-1)(x+1) ≡1(mod p)

故p必须整除x-1或x+1.由p是素数且 0<x<p,推出x=1或x=p-1.

利用二次探测定理,我们可以在利用费马小定理计算 a^(n-1) mod n的过程中增加对于整数n的二次探测.一旦发现违背二次探测条件,即可得出n不是素数的结论.

Accepted Code:

 1 #include <ctime>
 2 #include <iostream>
 3 using namespace std;
 4
 5 typedef long long LL;
 6
 7 LL mulMod(LL a, LL b, LL c) {
 8     LL res = 0;
 9     while (b) {
10         if (b&1) if ((res = (res + a)) >= c) res -= c;
11         a = a + a;
12         if (a >= c) a -= c;
13         b >>= 1;
14     }
15     return res;
16 }
17
18 LL powMod(LL a, LL b, LL c) {
19     LL res = 1;
20     while (b) {
21         if (b&1) res = mulMod(res, a, c);
22         a = mulMod(a, a, c);
23         b >>= 1;
24     }
25     return res;
26 }
27
28 bool isPrime(LL n) {
29     if (n <= 1) return false;
30     if (n == 2) return true;
31     if (n & 1 == 0) return false;
32     srand((LL)time(0));
33     LL u = n - 1, k = 0, pre;
34     while (!(u&1)) u >>= 1, k++;
35     for (int t = 0; t < 10; t++) {
36         LL a = rand() % (n - 2) + 2;
37         LL ans = powMod(a, n - 1, n);
38         for (int i = 0; i < k; i++) {
39             pre = ans;
40             ans = mulMod(ans, ans, n);
41             if (ans == 1 && (pre != 1 && pre != n - 1)) return false;
42             pre = ans;
43         }
44         if (ans != 1) return false;
45     }
46     return true;
47 }
48
49 int main(void) {
50     ios::sync_with_stdio(false);
51     int T;
52     cin >> T;
53     while (T--) {
54         LL n, k;
55         cin >> n >> k;
56         if (n < 2 * k) {
57             cout << "No" << endl;
58         } else {
59             if (k == 1) {
60                 if (isPrime(n)) cout << "Yes" << endl;
61                 else cout << "No" << endl;
62             } else if (k == 2) {
63                 if (n % 2 == 0) cout << "Yes" << endl;
64                 else if (isPrime(n - 2)) cout << "Yes" << endl;
65                 else cout << "No" << endl;
66             } else {
67                 cout << "Yes" << endl;
68             }
69         }
70     }
71     return 0;
72 }
时间: 2024-08-29 22:57:29

Hackerrank--Prime Sum的相关文章

Project Euler:Problem 50 Consecutive prime sum

The prime 41, can be written as the sum of six consecutive primes: 41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive primes that adds to a prime below one-hundred. The longest sum of consecutive primes below one-thousand that adds t

SGU 231.Prime Sum

题意: 求有多少对质数(a,b)满足a<=b 且a+b也为质数.(a+b<=10^6) Solution: 除了2之外的质数都是奇数,两个奇数的和是偶数,不可能是质数.所以题目就是求差为2的质数对的个数. 先用筛法刷出10^6内的质数,用bool数组标记(int型数组会超内存),然后扫一遍筛出来的质数,统计满足要求的答案就行了. #include <iostream> using namespace std; const int INF = 1000002; bool f[INF]

SGU 231 Prime Sum 求&lt;=n内有多少对素数(a,b)使得a+b也为素数 规律题

题目链接:点击打开链接 题意: 求<=n内有多少对素数(a,b)使得a+b也为素数 思路: 我们发现所有素数间隔都是>=2的,且除了2都是奇数,那么: 奇数+奇数 = 偶数. 所以只有一种情况2+素数=素数. 所以打个素数表,看一下有多少个素数和前面那个素数间隔是2的. #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <

HackerRank - &quot;Maximise Sum&quot;

It is modulo version of "max sum of contiguous subarray". So similar pattern can be applied too, but with tricks regarding to modulo ops. I checked editorials, and found that, the quick\correct solution requires sharp insight into internal chara

[Hackerrank] Prime Number Less Than N

static int getNumberOfPrimes(int N) { int n = N+1;//to include 0 as the first number for easy index operations later final boolean a[] = new boolean[n]; //Initialized to null by default. Arrays.fill(a, true); a[0] = false; a[1] = false; for (int i =

hoj 1004 Prime Palindromes(还是不够完美)

The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b

POJ_3421_X-factor Chains(素数筛法)

X-factor Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5659   Accepted: 1786 Description Given a positive integer X, an X-factor chain of length m is a sequence of integers, 1 = X0, X1, X2, -, Xm = X satisfying Xi < Xi+1 and Xi

C# 实例练习(第二天)

实例练习 1. 完成简单登录效果,设置用户登录账号密码,清空控制台,进入登录页面,请求用户输入账号.密码和验证码(随机产生),并判断用户输入的信息,给出相应的提示. C#代码如下: 主要知识点: (1)//清空控制台 Console.Clear(); (2)//设置随机数验证码 Random rand = new Random(); int num = rand.Next(1000,10000); 1 //账户设置界面 2 /* 3 Console.WriteLine("----------账户

网页特殊符号HTML代码大全

HTML特殊字符编码大全:往网页中输入特殊字符,需在html代码中加入以&开头的字母组合或以&#开头的数字.下面就是以字母或数字表示的特殊符号大全.                         ′ ´ ? © > > μ µ ? ® & & ° ° ? ¡     ? » | ¦ ÷ ÷ ? ¿ ? ¬ § § ? • ? ½ ? « ? ¶ ¨ ¨ ? ¸ ? ¼ < < ± ± × × ¢ ¢ ? ¾ ˉ ¯ " " ?

数的hash;

1.数的哈希一般是讲较大的数转化为一定范围内的数,如112131321321 转化为100000以内,一般用%99991:就是自己构造hash函数,然后函数值在100000以内: 2.当出现相同的key值,即函数值时,要用链表串起: 3.例:poj 3349: #include<iostream>#include<stdio.h>using namespace std;const int prime=99991;int map[100100][10];struct Node{