数论的东西比较烦…最近脑子有点乱,学一点就赶紧记下来,以免忘了……
先贴个线性筛:
void shai()
{
for(int i = 2,tot = 0;i <= n;i ++)
{
if(!vis[i]) pri[++ tot] = i;//当i是素数时
for(int j = 1,m;j <= tot && (m = i * pri[j]) <= n;j ++)
{
vis[m] = 1;
if(i % pri[j] == 0) { break; }//pri[j]是i的最小质因子时,若继续枚举素数,则枚举的素数将不是m的最小质因子。因为i中可以分解出更小的质因子,显然这个更小的质因子也是m的质因子。***此时m的最小质因子指数不为1***
else ;//pri[j]不是i的一个因子时,pri[j]就是m的最小质因子。***此时m的最小质因子指数为1***
}
}
}
线性筛是 O(n) ,因为每个合数都被它的最小质因子筛去。
一、基本积性函数
1.欧拉函数( ϕ(n) )
ϕ(n)=n∏(1−1pi)
当n是质数,
ϕ(n)=n−1
。
当
n=p∗i
,其中p是i的一个因数,则因为
ϕ(i)=i∏(1−1pi)
,所以
ϕ(n)=n∏(1−1pi)=p∗i∏(1−1pi)=p∗ϕ(i)
。
当
n=p∗i
,p不是i的一个因数,则gcd(p,i)=1,所以根据积性函数得:
ϕ(n)=ϕ(p)∗ϕ(i)
。
代码:
void shai()
{
phi[1] = 1;
for(int i = 2,tot = 0;i <= n;i ++)
{
if(!vis[i]) pri[++ tot] = i,phi[i] = i - 1;
for(int j = 1,m;j <= tot && (m = i * pri[j]) <= n;j ++)
{
vis[m] = 1;
if(i % pri[j] == 0) { phi[m] = phi[i] * pri[j]; break; }
else { phi[m] = phi[i] * (pri[j] - 1); }
}
}
}
2.莫比乌斯函数( μ(n) )
定义:
所以:
当n是素数,显然 μ(n)=−1
当 n=p∗i ,其中p是i的一个因数,显然 p2|n ,所以 μ(n)=0
当 n=p∗i ,其中p不是i的一个因数,因数个数改变了奇偶性,显然 μ(n)=−μ(i)
代码:
void shai()
{
mu[1] = 1;
for(int i = 2,tot = 0;i <= n;i ++)
{
if(!vis[i]) pri[++ tot] = i,mu[i] = -1;
for(int j = 1,m;j <= tot && (m = i * pri[j]) <= n;j ++)
{
vis[m] = 1;
if(i % pri[j] == 0) { mu[m] = 0; break; }
else { mu[m] = -mu[i]; }
}
}
}
3.约数个数( d(n) )
d(n)=∏(ai+1)
,
ai
是
pi
的指数。
约数个数和分解后的指数的值密切相关,所以再记
cnt(n)
为n的最小质因数的指数。
当n是质数:
d(n)=2
,
cnt(n)=1
。
当
n=p∗i,p2|i
,相当于p的指数增加了1,
cnt(n)=cnt(i)+1
。因为
d(n)=∏(ai+1)
,所以
d(n)=d(i)cnt(i)+1∗(cnt(n)+1)
当
n=p∗i
,p不是i的因数,此时p的
ai
为1,因为
d(n)=∏(ai+1)
,所以
d(n)=d(i)∗2
,
cnt(n)=1
代码:
void shai()
{
d[1] = 1;
for(int i = 2,tot = 0;i <= n;i ++)
{
if(!vis[i]) pri[++ tot] = i,d[i] = 2,cnt[i] = 1;
for(int j = 1,m;j <= tot && (m = i * pri[j]) <= n;j ++)
{
vis[m] = 1;
if(i % pri[j] == 0) { cnt[m] = cnt[i] + 1; d[m] = d[i]/(cnt[i] + 1) * (cnt[m] + 1); break; }
else { cnt[m] = 1; d[m] = d[i] << 1; }
}
}
}
还有一些积性函数,比如:
4.常函数1( 1 )
就是1。
5.id(id(i) )
id(i)=i
6.e( e(i) )
二、莫比乌斯反演/狄利克雷积
狄利克雷积:
设
f(n)和g(n)
都是积性函数。
f∗g和f×g 都是积性函数。
可以写成
莫比乌斯反演:
设 f(n)=∑d|nF(d) ,则
可以各种简化运算和转化问题…
三、一些公式的推导
设
f(n)=1n
,
f(n)=∑d|nF(d)
,那么
F(n)=∑d|nμ(d)∗f(nd)
。
奇怪的小技巧
筛积性函数注意推
f(pk)
。
二维问题先思考一维情况。
参考资料:《数论函数变换》——kAc