尤拉函式 (varphi)
(varphi(n)=)表示不超過 (n) 且與 (n) 互質的正整數的個數
[varphi(n)=ncdot prod_{i=1}^{s}(1-frac{1}{p_i})]
其中 (n = {p_1}^{alpha1} cdot {p_2}^{alpha2} cdots {p_s}^{alpha s} cdot) 是 (n) 的標準分解。
由此易見 ( ext{Euler}) 函式是積性函式。
線性求 ( ext{Euler}) 函式:
#define int long long
int phi[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getphi()
{
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(mark[i]==false)
{
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++)
{
if(i*prime[j]>n)
{
break;
}
mark[i*prime[j]]=true;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
for(int i=1;i<=n;i++)
{
phi[i]+=phi[i-1];
}
}
( ext{Mobius})函式 (mu(n))
[ mu(n)= egin{cases} 1&n=1\ 0&n ext{ 含有平方因子}\ (-1)^k&k ext{ 為 }n ext{ 的本質不同質因子個數} end{cases} ]
證明:
[ varepsilon(n)= egin{cases} 1&n=1\ 0&n
eq 1 end{cases} ]
其中 (displaystylevarepsilon(n)=sum_{dmid n}mu(d)) 即 (varepsilon=mu*1)
設 (displaystyle n=prod_{i=1}^k{p_i}^{c_i},n`=prod_{i=1}^k p_i)
那麼 (displaystylesum_{dmid n}mu(d)=sum_{dmid n`}mu(d)=sum_{i=0}^k C_k^icdot(-1)^k)
根據二項式定理,易知該式子的值在 (k=0) 即 (n=1) 時值為 (1) 否則為 (0) ,這也同時證明了 (displaystylesum_{dmid n}mu(d)=[n=1])
#define int long long
int mu[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getmu()
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(mark[i]==false)
{
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot;j++)
{
if(i*prime[j]>n)
{
break;
}
mark[i*prime[j]]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
}
( ext{Dirichlet})卷積
( ext{ID}: ext{ID(i)=i})
( ext{1}: ext{1(i)=1})
定義兩個數論函式的( ext{Dirichlet})卷積為:
[(f*g)(n)=sum_{d|n}({f(d) imes g(frac{n}{d})}) ]
性質:( ext{Dirichlet})卷積滿足交換律和結合律。
單位元:(varepsilon),(varepsilon(n)=[n==1]),任何函式卷(varepsilon)都為其本身.
(1*mu=varepsilon)
(mu * ext{ID} = varphi)
(1* ext{ID}=sigma)
莫比烏斯反演
公式:設 (f(n),g(n)) 為兩個數論函式。
如果有
[ f(n)=sum_{dmid n}g(d) ]
那麼有
[ g(n)=sum_{dmid n}mu(frac{n}{d})f(d) ]
證明:
原命題等價於:已知 (f=g*1) ,證明 (g=f*mu)
顯然: (f*mu=g*1*mu= g*varepsilon=g) (其中 (1*mu=varepsilon) )
同時,還有另一種( ext{Mobius})反演:
如果有
[ f(n)=sum_{nmid d}g(d) ]
那麼有
[ g(n)=sum_{nmid d}mu(frac{d}{n})f(d) ]
整除分塊
當遇到形如
[sum_{i=1}^{n}lfloor frac{n}{i}
floor]
的柿子時。
可以採用(O(sqrt {n}))複雜度的演算法:整除分塊
易證:對於部分連續的(i),(frac{n}{i})的值是相同的,考慮把它們合併計算,可以發現發現對於每一個值相同的塊,它的最後一個數是n/(n/i)
。
簡略證明:(frac{n}{i})就是所求的值,設為(x),那麼可證對於值(x),它所在的塊的最後一個數是(frac{n}{x})。
- 證明:反證法:對於數(frac{n}{x}+1),它所在的塊的值為(frac{n}{frac{n}{x}+1}),且(frac{n}{frac{n}{x}+1}-x=frac{x^2}{n+x}>0)。$ herefore (數)frac{n}{x}+1 (和數)frac{n}{x}$不在同一個塊中。
然後,原命題得證。
所以,易得計算原式方法。
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans+=(r-l+1)*(n/l);
}
P2257 YY的GCD
設(f(d)=sum_{i=1}^{n}sum_{i=1}^{m}[gcd(i,j)=d]),
(F(n)=sum_{nmid d}f(d)=lfloor frac{N}{n}
floor imes lfloor frac{M}{n}
floor)
由莫比烏斯反演:(f(n)=sum_{n|d}mu(frac{d}{n})F(d))
(Ans=sum_{i=1}^{n}sum_{i=1}^{m}[gcd(i,j)=prim])
(=sum_{pin prim}sum_{i=1}^{n}sum_{i=1}^{m}[gcd(i,j)=p])
(=sum_{pin prim}f(p))
(=sum_{pin prim}sum_{p|d}mu(frac{d}{p})F(d))
改為列舉(frac{d}{p}):
(Ans=sum_{pin prim}sum_{d}^{min(lfloor frac{n}{p}
floor,lfloor frac{m}{p}
floor)}mu(d)F(dp))
(=sum_{pin prim}sum_{d}^{min(lfloor frac{n}{p}
floor,lfloor frac{m}{p}
floor)}mu(d) imes lfloor frac{N}{dp}
floor imes lfloor frac{M}{dp}
floor)
設(dp=T,t=p)
(Ans=sum_{tin prim}sum_{d}^{min(lfloor frac{n}{t}
floor,lfloor frac{m}{t}
floor)}mu(frac{T}{t}) imes lfloor frac{N}{T}
floor imes lfloor frac{M}{T}
floor)
(=sum_{T=1}^{min(n,m)}sum_{tin prim,t|T}mu(frac{T}{t}) imes lfloor frac{N}{T}
floor imes lfloor frac{M}{T}
floor)
(=sum_{T=1}^{min(n,m)}(lfloor frac{N}{T}
floor imes lfloor frac{M}{T}
floor) imes sum_{tin prim,t|T}mu(frac{T}{t}))
程式碼:
//sum即為(sum_{tin prim,t|T}mu(frac{T}{t}))的字首和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int prime[10000005];
int mu[10000005];
ll f[10000005];
ll sum[10000005];
bool vis[10000005];
int cnt;
void init()
{
mu[1]=1;
for(int i=2;i<=10000000;i++)
{
if(vis[i]==false)
{
mu[i]=-1;
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
{
break;
}
mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=cnt;i++)
{
for(int j=1;j*prime[i]<=10000000;j++)
{
f[j*prime[i]]+=mu[j];
}
}
for(int i=1;i<=10000000;i++)
{
sum[i]=sum[i-1]+f[i];
}
}
ll solve(int a,int b)//運用整除分塊
{
ll ans=0;
if(a>b)
{
swap(a,b);
}
for(int l=1,r=0;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
ans+=(ll)(sum[r]-sum[l-1])*(a/l)*(b/l);
}
return ans;
}
signed main()
{
init();
int T;
cin>>T;
for(int i=1;i<=T;i++)
{
int a,b;
scanf("%d %d",&a,&b);
printf("%lld
",solve(a,b));
}
return 0;
}
常用柿子(待補充)
[[gcd(x,y)=1]=sum_{d|x,d|y}mu(d)]