線性篩各種函式
阿新 • • 發佈:2020-09-16
線性篩各種函式
線性篩素數
void make_prime(int x) {
for(int i = 2;i <= x; i++) {
if(!is_prime[i]) prime[++cnt] = i;
for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
is_prime[i * prime[j]] = 1;
if(!(i % prime[j])) break;
}
}
}
線性篩尤拉函式
void make_phi(int x) { phi[1] = 1; for(int i = 2;i <= x; i++) { if(!is_prime[i]) phi[i] = i - 1, prime[++cnt] = i; for(int j = 1;j <= cnt && i * prime[j] <= x; j++) { is_prime[i * prime[j]] = 1; if(!(i % prime[j])) { phi[i * prime[j]] = phi[i] * prime[j]; break; } phi[i * prime[j]] = phi[i] * (prime[j] - 1); } } }
線性篩莫比烏斯函式
void make_mu() { mu[1] = 1; for(int i = 2;i <= N - 5; i++) { if(!is_prime[i]) prime[++cnt] = i, mu[i] = -1; for(int j = 1;j <= cnt && i * prime[j] <= N - 5; j++) { is_prime[i * prime[j]] = 1; if(!(i % prime[j])) { mu[i * prime[j]] = 0; break; } mu[i * prime[j]] = -mu[i]; } } }
線性篩約數個數
void make_r(int x) { r[1] = 1; for(int i = 2;i <= x; i++) { if(!is_prime[i]) prime[++cnt] = i, r[i] = 2, num[i] = 1; for(int j = 1;j <= cnt && i * prime[j] <= x; j++) { is_prime[i * prime[j]] = 1; if(!(i % prime[j])) { num[i * prime[j]] = num[i] + 1; r[i * prime[j]] = r[i] / (num[i] + 1) * (num[i] + 2); break; } num[i * prime[j]] = 1; r[i * prime[j]] = r[i] * r[prime[j]]; } } }
線性篩約數和
void make_sd(int x) {
sd[1] = sp[1] = 1;
for(int i = 2;i <= x; i++) {
if(!is_prime[i])
prime[++cnt] = i, sd[i] = sp[i] = i + 1;
for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
is_prime[i * prime[j]] = 1;
if(!(i % prime[j])) {
sp[i * prime[j]] = sp[i] * prime[j] + 1;
sd[i * prime[j]] = sd[i] / sp[i] * sp[i * prime[j]];
break;
}
sp[i * prime[j]] = 1 + prime[j];
sd[i * prime[j]] = sd[i] * sd[prime[j]];
}
}
}
線性篩一個數的\(n\)次方
void make_id(int x) {
id[1] = 1;
for(int i = 2;i <= x; i++) {
if(!is_prime[i]) prime[++cnt] = i, id[i] = ksm(i, n);
for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
is_prime[i * prime[j]] = 1;
id[i * prime[j]] = id[i] * id[prime[j]] % mod;
if(!(i % prime[j])) break;
}
}
}
線性篩狄利克雷卷積
一般要找出\(f(p^k)\)的規律,方法就是打個表,下面以\(\phi *\mu\)為例:
void make_f() {
f[1] = 1;
for(int i = 2;i <= N - 5; i++) {
if(!is_prime[i]) prime[++cnt] = i, f[i] = i - 2;
for(int j = 1;j <= cnt && i * prime[j] <= N - 5; j++) {
is_prime[i * prime[j]] = 1;
if(!(i % prime[j])) {
if((i / prime[j]) % prime[j]) f[i * prime[j]] = f[i / prime[j]] * 1ll * (prime[j] - 1) * (prime[j] - 1);
else f[i * prime[j]] = f[i] * prime[j];
break;
}
f[i * prime[j]] = f[i] * (prime[j] - 2);
}
}
}