震惊!某OIer竟使用(O(n^2))筛法长达1年!
原来筛欧拉函数是和筛素数差不多的,一个埃氏筛法,一个线性筛...
要实现线性筛,必须先明确欧拉函数的以下性质:
设(p)为素数,则有
- (varphi(p) = p-1)
- (如果i与p互质, 那么 varphi(i * p) = varphi(i) * (p-1))
- (如果i与p不互质, 那么 varphi(i * p) = varphi(i) * p)
代码如下:
void get_phi(long long n) {
p[1] = 1;
for(long long i = 2; i <= n; i++) {
if(!flag[i]) {
prime[++cnt] = i;
p[i] = i-1;
}
for(long long j = 1; j <= cnt && i*prime[j] <= n; j++) {
flag[i*prime[j]] = true;
if(i%prime[j])
p[i*prime[j]] = p[i]*(prime[j]-1);
else {
p[i*prime[j]] = p[i]*prime[j];
break;
}
}
}
}