一些定义
数论函数:定义域在正整数的函数
积性函数:(forall aperp b,f(ab)=f(a) imes f(b))
完全积性函数:(forall a,b,f(ab)=f(a) imes f(b))
栗子
- 常数函数$$1(i)=1$$
- 幺元函数$$e(n)=[n=1]$$
- 恒等函数$$id(n)=n$$
欧拉函数
(phi(i))表示(1-i)中与(i)互质的数的个数
引理:
- 如果(n)为素数p,(phi(n)=n-1)
- 如果(n)为素数的次方,(phi(p^a)=(p-1) imes p^{a-1})
- 如果(n)为两数之积,(phi(a imes b)=phi(a) imesphi(b))
- 若(n=p_1^{a1} imes p_2^{a2} imes... imes p_k^{ak}), (phi(n)=n imes (1-1/p_1) imes (1-1/p2) imes ... imes(1-1/p_k))
欧拉定理
(IF aperp m, a^{phi(m)}equiv 1 (mod m))
欧拉函数的线性筛法
- 性质1 (phi(p)=p-1)
- 性质2 (IF i mod p=0, (i*p)=p*phi(i))
证明
( ecause n)与(i)不互质,( herefore i)与(n+i)不互质
( ecause [1,i])中不与i互质的数有(i-phi (i))个,
( herefore(i+1,p imes i])中一共有(p imes phi(i))个数(perp i imes p) - 性质3 (IF i mod p eq0, (i*p)=(p-1)*phi(i))
调和级数
除数函数
(sigma_0)表示因子个数
(sigma_1)表示因子和
积性函数
狄利克雷卷积
有交换律和结合律
如果(f,g)都是积性函数,(h)是积性函数
- 验证卷积[h(p^k)=sum_{i=0}^kf[(p^i) imes g(p^{k-i}) ]
栗子
- (varphi*1=id)即(sum_{d|n}varphi(d)=n)
- (varphi=mu *id)
- (sigma=id*e)
- (e=mu*1)
- (id=varphi*1)
给定(f,g),求卷积前n项的做法-->暴力(O(n ln n))
莫比乌斯函数
积性函数,但不是完全积性函数
证明:
当(p_1perp d) ,$$mu(dp_1)=mu(d) imesmu(p_1)=-mu(d)$$
线性筛法
void Linear_Shaker(int n)
{
mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!ism[i]) {prm[++tot] = i; mu[i] = -1;}
for (int j = 1; j <= tot; j++)
{
int num = prm[j] * i;
if (num > n) break;
ism[num] = 1;
if (i % prm[j] == 0) break;
mu[num] = -mu[i];
}
}
}
莫比乌斯反演
如果知道(f,1)直接求就行了啊
但是如果只知道(g,f)呢
反演!!!
就是说
栗子
-
[g(k)=sum_{pin Pwedge pd=k}mu(d) ][f(p)=[pin P] ][g(k)=sum_{pd=k}mu(d)*f(p) ]
预处理卷积!!
然后每组询问的答案变成$$sum_{k=1}^{min(n,m)} lfloor frac n k floorlfloor frac m k floor g(k)$$
(lfloor frac n k floorlfloor frac m k floor)只有(O(sqrt n))种取值
-
也就是说((i,j)=sigma(gcd(i,j)))
记(f_a[d])表示(gcd(i,g)=d)的格子的贡献
[f_a[d]=left{egin{matrix}0,&sigma(d)>a&\ sigma(d),&oterwiseend{matrix} ight. ][ans=sum_df_a[d]sum_kmu(k)lfloorfrac n{dk} floorlfloorfrac m {dk} floor=sum_tlfloorfrac n t floorlfloorfrac m t floor(sum_{dk=t}f_a[d]mu(k)) ]把所有变量离线下来,每次修改改变的h复杂度(O(n ln n))
杜教筛
-
(summu)
[mu*1=e ][f(n)=1-sum^n_{i=2}f(lfloor frac n i floor) ]预处理前(n^{frac 23})的(mu)时间复杂度是(O(n^{frac 2 3}))
int Mu(int n)
{
if(n<N) return mu[n];
if(mu[n]) return mu[n];
int res=0;
for(int l=2,r;l<=n;l=r+1)
{
r=n/(n/l);
res+=(r-l+1)*Mu(n/l);
}
return mu[n]=1-res;
}
- $sumvarphi$
同↑
```cpp
int Phi(int n)
{
if(n<=N) return phi[n];
if(P[n]) return P[n];
int res=0;
for(int l=2,r;l<=n;l=r+1)
{
r=n/(n/l);
res+=(r-l+1)*Phi(x/i);
}
return P[n]=n*(n+1)/2-res;
}
拉格朗日插值
给出n个点((x_i,y_i)) 找出一个过所有点的多项式(f(x))
对于每一个点找一个函数使这个函数只在对应 (x_i)时取值是(y_i)其余(x)取值都是0
预处理(P(x)=prod(x-x_i)) (n^2)求出(f(x))