Give you a prime number p, if you could find some natural number (0 is not inclusive) n and m, satisfy the following expression:
We call this p a “Special Prime”.
AekdyCoin want you to tell him the number of the “Special Prime” that no larger than L.
For example:
If L =20
1^3 + 71^2 = 2^3
8^3 + 198^2 = 12^3
That is to say the prime number 7, 19 are two “Special Primes”.
Input
The input consists of several test cases.
Every case has only one integer indicating L.(1<=L<=10^6)
Output
For each case, you should output a single line indicate the number of “Special Prime” that no larger than L. If you can’t find such “Special Prime”, just output “No Special Prime!”
Sample Input
7
777
Sample Output
1
10
Hint
题意:p是一个素数,存在两个非零自然数n,m使得n ^ 3+p*n^2=m ^ 3,就说p是一个特殊素数。现在给出一个数L,求小于L的特殊素数的个数。
思路:
因为p是质数,所以gcd(n,n+p)的值为1或者p,分两种情况考虑,如果值为p,那么设 n=xp,x是正整数。
那么(x ^3 +x ^ 2)p ^3=m ^3 ,m=p *( x^3 +x ^ 2)^(1/3) 显然,(x ^ 3+x^ 2)^(1/3)不是整数。所以n不能是p的倍数。
所以n,p互质 ,n^2和(n+p)也互质。
n ^ 2(n+p)=m ^3 式子右边每种质因子有3的整数倍个,相应的左边应该也是,设n=A^3, n+p=B^3 ,
那么p=B ^3 - A^3=(B-A)*(A ^2 +B ^2+AB) ,p是质数,那么 B-A等于1.
那么p=3A^2+3A+1.
所以只要能找到一个正整数A,满足p=3A^2+3A+1.那么p是Special Primes
去处理出所有的Special Primes,求一下前缀和。就可以每次查询在O(1)的时间查询出来。
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 5000000 + 5;
bool prime[N];
int p[N], tot=0,a[N];
void inits()
{
for(int i = 2; i < N; i ++) prime[i] = true;
for(int i = 2; i < N; i++){
if(prime[i]) p[tot ++] = i;
for(int j = 0; j < tot && i * p[j] < N; j++){
prime[i * p[j]] = false;
if(i % p[j] == 0) break;
}
}
}
int main(){
inits();
for(int i=0;i<tot;i++)
{
int x=p[i];
int j=1;
while(3*j*j+3*j+1<x)j++;
if(3*j*j+3*j+1==x)
a[x]++;
}
for(int i=1;i<N;i++)
a[i]+=a[i-1];
int n;
while(scanf("%d",&n)!=EOF)
{
int t;
t=a[n];
if(t)
printf("%d\n",t);
else
printf("No Special Prime!\n");
}
}
题解是大佬写的https://blog.csdn.net/weixin_42757232/article/details/89788524,这个思路来的有点突然,能看懂但是让我自己想我肯定是想不到的。