筛素数:
int cnt,pri[maxn];
bool vis[maxn];
void get_pri(int n)
{
for(int i = 2;i <= n;i++)
{
if(!vis[i]) pri[++cnt] = i;
for(int j = 1;j <= cnt && i*pri[j] <= n;j++)
{
vis[i*pri[j]] = true;
if(i%pri[j] == 0) break;
}
}
}
筛莫比乌斯函数:
int cnt,pri[maxn],mu[maxn];
bool vis[maxn];
void get_mu(int n)
{
mu[1] = 1;
for(int i = 2;i <= n;i++)
{
if(!vis[i])
{
pri[++cnt] = i;
mu[i] = -1;
}
for(int j = 1;j <= cnt && i*pri[j] <= n;j++)
{
vis[i*pri[j]] = true;
if(i%pri[j] == 0) break;
mu[i*pri[j]] = -mu[i];
}
}
}
筛欧拉函数:
int cnt,pri[maxn];
ll phi[maxn],sum1[maxn];
bool vis[maxn];
void get_phi(int n)
{
phi[1] = 1;
for(int i = 2;i <= n;i++)
{
if(!vis[i])
{
pri[++cnt] = i;
phi[i] = i-1;
}
for(int j = 1;j <= cnt && i*pri[j] <= n;j++)
{
vis[i*pri[j]] = true;
if(i%pri[j] == 0)
{
phi[i*pri[j]] = phi[i]*pri[j];
break;
}
phi[i*pri[j]] = phi[i]*(pri[j]-1);
}
}
}
筛约数个数和函数:
维护
d
(
n
)
d(n)
d(n) 需要额外维护一个数组
n
u
m
[
i
]
num[i]
num[i] 表示
i
i
i 的最小质因子的指数
int cnt,pri[maxn],d[maxn],num[maxn];
bool vis[maxn];
void get_d(int n)
{
d[1] = 1;
for(int i = 2;i <= n;i++)
{
if(!vis[i])
{
pri[++cnt] = i;
d[i] = 2;num[i] = 1;
}
for(int j = 1;j <= cnt && i*pri[j] <= n;j++)
{
vis[i*pri[j]] = true;
if(i%pri[j] == 0)
{
d[i*pri[j]] = d[i]/(num[i]+1)*(num[i]+2);
num[i*pri[j]] = num[i]+1;
break;
}
d[i*pri[j]] = d[i]*2;
num[i*pri[j]] = 1;
}
}
}
筛约数和函数:
σ
(
n
)
=
∏
i
=
1
k
∑
j
=
0
a
i
p
i
j
\sigma(n)=\prod_{i=1}^k\sum_{j=0}^{a_i}p_i^j
σ(n)=∏i=1k∑j=0aipij
=
(
1
+
p
1
+
p
1
2
+
.
.
.
+
p
1
a
1
)
(
1
+
p
2
+
p
2
2
+
.
.
.
+
p
2
a
2
)
.
.
.
(
1
+
p
k
+
p
k
2
+
.
.
.
+
p
k
a
k
)
=(1+p_1+p_1^2+...+p_1^{a_1})(1+p_2+p_2^2+...+p_2^{a_2})...(1+p_k+p_k^2+...+p_k^{a_k})
=(1+p1+p12+...+p1a1)(1+p2+p22+...+p2a2)...(1+pk+pk2+...+pkak)
发现
∑
j
=
0
a
i
p
i
j
\sum_{j=0}^{a_i}p_i^j
∑j=0aipij 是个等比数列的和,可以快速算出,故需要额外维护一个数组来表示这个和
int cnt,pri[maxn],sumd[maxn],sp[maxn];
bool vis[maxn];
void get_sumd(int n)
{
sumd[1] = 1;
for(int i = 2;i <= n;i++)
{
if(!vis[i])
{
pri[++cnt] = i;
sumd[i] = sp[i] = i+1;
}
for(int j = 1;j <= cnt && i*pri[j] <= n;j++)
{
vis[i*pri[j]] = true;
if(i%pri[j] == 0)
{
sp[i*pri[j]] = sp[i]*pri[j]+1;
sumd[i*pri[j]] = sumd[i]/sp[i]*sp[i*pri[j]];
break;
}
sumd[i*pri[j]] = sumd[i]*sumd[pri[j]];
sp[i*pri[j]] = pri[j]+1;
}
}
}