cf Double Happiness(判断是否为素数且为4k+1型)
2790. Double Happiness
time limit per test
3 secondsmemory limit per test
128 megabytesinput
standard inputoutput
standard outputOn the math lesson a teacher asked each pupil to come up with his own lucky numbers. As a fan of number theory Peter chose prime numbers. Bob was more original. He said that number t is his lucky number, if it can be represented as:
Now, the boys decided to find out how many days of the interval [l,r] (l≤r) are suitable for pair programming. They decided that the day i(l≤i≤r) is suitable for pair programming if and only if the number i is lucky for Peter and lucky for Bob at the same time. Help the boys to find the number of such days.
Input
The first line of the input contains integer numbers l,r (1≤l,r≤3·108).
Output
In the only line print the number of days on the segment [l,r], which are lucky for Peter and Bob at the same time.
Examples
Input
3 5
Output
1
Input
6 66
Output
7
题目分析:
两位同学的幸运数字一个是为素数,一个是可以表示为两整数平方和的数字。
这里只是想补充一个数论的知识:一个4k+1型的素数,一定可以分解为两个整数的平方和。
知道了这个知识后,一定程度上简化此题。最后一个要解决的问题就是,如何快速的判断一个较大数字是否为素数。
这个地方需要,了解“埃拉托斯特尼筛法”,以下简称埃氏筛。
所谓“埃氏筛”就是,要得到n以内的所有素数,必须把不大于n的所有素数的整数倍剔除,剩下的数字就是素数。
另外r,l的取值范围最大取到3e8,如果建立一个容量是3e8的bool型数组,必定要炸内存,所以要设法精简下。
· 所有的素数都是奇数,所有可以找到一种对应关系,3/2=1,5/2=2,7/2=3,嗯,这样就可以把数组的长度折半。
b[n>>1]
#include <stdio.h> #include <iostream> #include <vector> using namespace std; const long maxn = 3e8 + 5; vector<bool> b(maxn >> 1, 0);//集体赋为0 int main() { long l; long r; long i; long j; for (i = 3; i*i <= maxn; i += 2)//埃氏筛 if (!b[i >> 1])//0 is 素数 for (j = i * i; j <= maxn; j += (i << 1)) { b[j >> 1] = 1;//1 is 非素数 } while (cin >> l >> r) { long ans = 0; if (l <= 2 && r >= 2) ans++; while (l % 4 != 1)l++; while (r % 4 != 1)r--; for (i = l; i <= r; i += 4) if (i >= l && !b[i >> 1]) ans++; cout << ans << endl; } return 0; }