我的思路:這個是歐拉定理篩選法的應用,令sum(a) = (1) + (2) + ……+(a)
那麼此題可以變換為求sum(b) - sum(a - 1),如果設定sum函數每次求一遍可能會逾時,因此打出sum表。
設程式可知eular(3000000) = 8000000,所以可能超過整型,在此用長整型。
結果顯示超記憶體,現在來計算一下記憶體:
長整型佔8個位元組,maxn = 3000000*8 = 24000000 = 24000K;顯示35732k大致相近,而題目要求32768k內。。。
既然是超記憶體不時逾時,那麼可以用sum函數求,代替打表法。
終於過了。。。orz
#include <cstdio>#include <iostream>using namespace std;typedef long long LL;const int MAXN = 3001000;int eulars[MAXN];//int sum[MAXN];//求數組eulars(i)的常式,n為最大的i+1//即求出n-1及以下的所有eular函數值inline void GetEular(int n){ int i,j,pNum=0; memset(eulars,0,sizeof(eulars)); eulars[1]=1; for(i=2;i<n;i++) { if(!eulars[i]) for(j=i;j<n;j+=i) { if(!eulars[j]) eulars[j]=j; eulars[j]=eulars[j]/i*(i-1); } } return ;}/*void test() { int a = 3000000; GetEular(MAXN); cout << eulars[a] << endl; return ;}*//*inline void GetSum() { memset(sum, 0, sizeof(sum)); for(int i = 1; i < MAXN; i++) { sum[i] = sum[i - 1] + eulars[i]; }}*/int main() { //test(); GetEular(MAXN); //GetSum(); int a, b; long long sum = 0; while(~scanf("%d%d", &a, &b)) { sum = 0; for(int i = a; i <= b; i++) sum += eulars[i]; printf("%I64d\n", sum); } return 0;}