基本都是看jzp線性篩的...這些篩法都是O(n)的...比O(nloglogn)的算法優化了不少...算法
主要思路都是對於每個合數n,都由n的最小素因子惟一進行標記,避免了埃拉託斯特尼篩法的重複標記函數
在處理歐拉和莫比烏斯函數的時候其實已經順便篩了素數了...積性函數的性質是厲害...優化
int cnt;
int prime[MAXN]; int pri[MAXN]; int phi[MAXN]; int miu[MAXN]; /* 素數篩 */ void pre_prime(){ mem(prime,0); cnt = 0;
prime[0] = prime[1] = 1; for(int i = 2 ; i < MAXN ; i++){ if(!prime[i]) pri[cnt++] = i; for(int j = 0 ; j < cnt && i * pri[j] <= MAXN ; j++){ prime[i * pri[j]] = 1; if(i % pri[j] == 0) break; } } } /* 莫比烏斯篩 */ void pre_miu(){ mem(prime,0); cnt = 0; miu[1] = 1; for(int i = 2 ; i < MAXN ; i++){ if(!prime[i]){ miu[i] = -1; pri[cnt++] = i; } for(int j = 0 ; j < cnt && i * pri[j] <= MAXN ; j++){ prime[i * pri[j]] = 1; if(i % pri[j] == 0){ miu[i * pri[j]] = 0; break; }else miu[i * pri[j]] = -miu[i]; } } } /* 歐拉篩 */ void pre_phi(){ mem(prime,0); cnt = 0; phi[1] = 1; for(int i = 2 ; i < MAXN ; i++){ if(!prime[i]){ miu[i] = -1; pri[cnt++] = i; } for(int j = 0 ; j < cnt && i * pri[j] <= MAXN ; j++){ prime[i * pri[j]] = 1; if(i % pri[j] == 0){ phi[i * pri[j]] = phi[i] * pri[j]; break; }else phi[i * pri[j]] = phi[i] * (pri[j] - 1); } } }