ZOJ Goldbach 素数去重(2013 ACM/ICPC Asia Regional Changsha Online G)
Goldbach
Fancy is learning mathematics recently. He's already mastered the use of multiplication and addition days before, so today he's going to learn prime number.
After reading the learning material, he's been asked to complete a simple test. He's been given an integer X larger than 1, using multiplication, addition and at most 3 prime numbers, how many ways could he get the answer as X exactly?
Since that Fancy is a new learner of mathematics, he's still not familiar with brackets. So in the calculation, the addition is always performed after multiplication.
Input
There will be multiple test cases. Each test case contains a single integer X (1 < X ≤ 80000) in one line.
Output
For each test case, please calculate the number of ways which Fancy could get the answer as X. Since that the number of ways might be large, please output it modulo 1000000007.
Sample Input
5 10 8
Sample Output
2 4 4
Hint
In the 3rd case, 8 = 2 * 2 * 2 = 2 + 2 * 3 = 2 + 3 + 3 = 3 + 5, so the answer is 4.
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <vector> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 100005 12 #define mod 1000000007 13 #define INF 0x7fffffff 14 #define ll long long 15 //#define ll __int64 16 ll prv[maxn]; 17 ll pri[maxn]; 18 ll num[maxn]; 19 int n,m; 20 void init(){ 21 for(int i=2;i*i<=80005;i++){ 22 if(!prv[i]) 23 for(int j=i*i;j<=80005;j+=i) 24 prv[j]=1; 25 } 26 int k=0; 27 for(int i=2;i<=80005;i++) 28 if(!prv[i])pri[k++]=i; 29 for(int i=0;i<k&&pri[i]<=80005;i++) 30 for(int j=i+1;j<k&&pri[i]+pri[j]<=80005;j++) 31 num[pri[i]+pri[j]]++; 32 } 33 int main(){ 34 init(); 35 while(~scanf("%d",&n)){ 36 int k=0; 37 ll s=0,sum=0; 38 for(int i=2;i<=n;i++)if(!prv[i])k++; 39 if(!prv[n])s++; 40 else for(int i=0;i<k&&pri[i]<n;i++)if(n%pri[i]==0&&!prv[n/pri[i]]){s++;break;} 41 else for(int j=i;j<k&&pri[i]*pri[j]<n;j++)if(n%(pri[i]*pri[j])==0&&!prv[n/pri[i]/pri[j]]){s++;i=k;break;} 42 for(int i=0;i<k&&pri[i]<n;i++) 43 for(int j=0;j<k&&pri[j]*pri[j]<=n-pri[i];j++) 44 if((n-pri[i])%pri[j]==0&&!prv[(n-pri[i])/pri[j]])s++; 45 for(int i=0;i<k&&pri[i]<n;i++){ 46 ll t=n-pri[i]; 47 sum+=num[t]; 48 if(t-pri[i]>=2&&!prv[t-pri[i]]&&pri[i]*3!=n)sum--; 49 } 50 s=s+sum/3; 51 for(int i=0;i<k;i++)if(n-2*pri[i]>=2&&!prv[n-2*pri[i]])s++; 52 sum=0; 53 for(int i=0;i<k&&pri[i]<n;i++){ 54 if(!prv[n-pri[i]])sum++; 55 if(pri[i]*2==n)sum++; 56 } 57 s=s+sum/2; 58 if(n<=1)s--; 59 printf("%lld\n",s); 60 } 61 return 0; 62 }
浙公网安备 33010602011771号