Special PrimeTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 680 Accepted Submission(s): 360 Problem Description 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 + 7*1^2 = 2^3 8^3 + 19*8^2 = 12^3 That is to say the prime number 7, 19 are two “Special Primes”. Input The input consists of several test cases. 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 Source |
还是那句话:也不是在下不谦虚,要是不看题解,我这辈子都写不出来。
思路:题解源于acdreamers
题意:在区间[2,L]内,有多少个素数p,满足方程有解。
分析:n^b + p*n^(b-1) = m^b ==> n^(b-1)*[n+p]=m^b
因为n里面要么有p因子,要么没有,所以gcd(n^(b-1),n+p)=1或(含有p因子的数)
当gcd(n^(b-1),n+p)== (含有p因子的数)的时候,显然无解,因为假设有解,那么n=K*p , K^(b-1)*p^b*(K+1)
如果希望上面的==m^b,那么K^(b-1) *(K+1)必须能表示成某个数X的b次方,而gcd(K,K+1)=1,所以他们根本就没共同因
子,所以没办法表示成X的b次方,所以gcd(n^(b-1),n+p)=1
假设n=x^b,n+p=y^b,那么显然m=x^(b-1)*y,而p=y^b-x^b
显然(y-x)|p,那么必须有y-x=1,所以y=x+1,代上去就发现,p=(x+1)^b-x ^b。所以枚举x,然后判断p是否是素数即可。
这里就可以推出来 p = 3*x^2 + 3*x + 1;
#include <bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
#define line cout<<"---------------------"<<endl;
typedef long long ll;
const int maxn = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const int Mod = 1e9 + 7;
const int N = 1010;
bool prime[maxn];
void Is_prime(){
memset(prime,true,sizeof(prime));
prime[0] = prime[1] = false;
for(int i=2;i*i<=maxn;i++){
if(prime[i]){
for(int j=2;i*j<=maxn;j++){
prime[i*j] = false;
}
}
}
}
int main(){
int n;
Is_prime();
while(scanf("%d",&n)!=EOF){
int num=0;
for(int i=1;;i++){
int tmp = 3*i*i + 3*i + 1;
if(tmp > n) break;
if(prime[tmp])
num++;
}
if(!num) printf("No Special Prime!\n");
else printf("%d\n",num);
}
return 0;
}