复习数论
线性筛
int P[Max],cnt;
bool vis[Max];
int GetP(int n)
{
pos(i,1,n) vis[i]=true;
vis[1]=false;
pos(i,2,n)
{
if(vis[i]) P[++cnt]=i;
for(int j=1;j<=cnt && i*P[j]<=n;j++)
{
vis[i*P[j]]=false;
if(i%P[j]==0) break;
}
}
}
欧拉函数
单个数
\(𝜓(𝑎)=\prod_{i=1}^n 𝜓({𝑝_i}^{k_i})=\prod_{i=1}^n{𝑝_i}^{k_i}\prod_{i=1}^n (1-\frac{1}{p_i}) =a\prod_{i=1}^n(1-\frac{1}{p_i})\)
\(O(\sqrt n)\)可求出
int phi(int x)
{
int ans=x;
pos(i,2,sqrt(x))
{
if(n%i==0)
{
ans=ans/i*(i-1);//先除后乘防止爆int
while(n%i==0)n/=i;//筛去互质因子的幂次
}
}
if(n>1) ans=ans/n*(n-1);//最后可能有剩余
return ans;
}
线性筛求欧拉函数
\(𝜓(𝑎)=\prod_{i=1}^n 𝜓({𝑝_i}^{k_i})=\prod_{i=1}^n{𝑝_i}^{k_i}\prod_{i=1}^n (1-\frac{1}{p_i}) =a\prod_{i=1}^n(1-\frac{1}{p_i})\)
\(O(n)\)
int P[Max],Phi[Max],cnt;
bool vis[Max];
void Euler(int n)
{
pos(i,1,n) vis[i]=true;
vis[1]=false;
pos(i,2,n)
{
if(vis[i]) P[++cnt]=i,Phi[i]=i-1;
for(int j=1;j<=cnt && i*P[j]<=n;j++)
{
vis[i*P[j]]=false;
if(i%P[j]==0)
{
Phi[i*P[j]]=Phi[i]*P[j];//如果因子已经参与运算,相当于只改变上式的a
break;
}
else Phi[i*P[j]]=Phi[i]*(P[j]-1);//第一次参与,乘p*(1-1/p)
}
}
}