[浅谈] 欧拉函数
definition
\(\varphi(n)\) 表示不超过 \(n\) 且与 \(n\) 互质的正整数的个数。
欧拉函数是一个数论函数(定义域为正整数)和积性函数(对于互质的正整数 \(a,b\) 满足 \(f(a,b)=f(a)f(b)\) )
积性函数的性质:
\(n=\prod p_i^{a_i}(p_i为质数)\)
\(f(n)=\prod f(p_i^{a_i})\) 。
theorem
- \(\varphi(p)=p-1(p为质数)\)
- \(\varphi(p^a)=p^a-p^{a-1}=(p-1)p^{a-1}(p为质数)\)
因为 \(px\) 与 \(p^a\) 不互质,总共有 \(p^{a-1}\) 个这样的数,剩下的数就是与它互质的数。 - 由 \(2\) 推得: \(\varphi(n)=\prod\varphi(p_i^{s_i}),\varphi(n)=\prod(p_i-1)p_i^{s_i-1}=n\prod(1-\frac{1}{p_i})\)
- 由积性函数:\(\varphi(2n)=\varphi(n)(n为奇数)\)
- \(n=\sum\limits_{d|n} \varphi(d)\)
- \(\varphi(n) 为偶数(n>2)\)
- 欧拉定理: 对于互质正整数 \(a,m\) 且 \(m\ge 2\) ,\(a^{\varphi(m)}\equiv 1(\mod m)\)
- 费马小定理: 对于质数 \(m\) 且 \(a\) 不为 \(m\) 的倍数, \(a^{m-1}\equiv1(\mod m)\)
- 拓展欧拉定理:
\((a,m)=1,则a^b\equiv a^{b\mod \varphi(m)}(\mod m)\)
\(b\ge \varphi(m),则a^b\equiv a^{(b\mod \varphi(m))+\varphi(m)}(\mod m)\)
例题:
P4139 上帝与集合的正确用法
CF906D Power Tower
定义求欧拉函数
点击查看代码
int phi(int x){
int p=1;
for(int i=2;i*i<=x;i++){
if(x%i)continue;
p*=i-1;x/=i;
while(x%i==0)p*=i,x/=i;
}
if(x>1)p*=x-1;
return p;
}
筛法求欧拉函数
点击查看代码
phi[1]=1;bk[1]=1;
for(int i=2;i<=maxn;i++){
if(!bk[i]){
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++){
if(i*prime[j]>maxn)break;
bk[i*prime[j]]=1;
phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
if(i%prime[j]==0)break;
}
}
CF906D Power Tower
拓欧的应用不过是给指数运算取模罢了。
\(w_{l+1}^{w_{l+2}^{...}}\ge \varphi(P)\Rightarrow w_{l}^{w_{l+1}^{...}}\mod P=w_l^{w_{l+1}^{w_{l+2}}\mod \varphi(P)+\varphi(P)}\mod P\)
\(w_{l+1}^{w_{l+2}^{...}}< \varphi(P)\Rightarrow w_{l}^{w_{l+1}^{...}}\mod P=w_l^{w_{l+1}^{w_{l+2}}\mod \varphi(P)}\mod P\)
递归终点显然是 \(P=1\) 或 \(l=r\) 。因为 \(P\) 下降的很快,大概是 \(\log\) 级别,所以直接递归即可,不用优化。
那么剩下的问题就在分类上了:我们不知道 \(w_{l+1}^{w_{l+2}^{...}},\varphi(P)\) 之间的大小关系。
一种可行的方法是对取模做手脚,取模时对于 \(x>P\) 时,变为 \(x \mod P+P\) 。 这样倘若大于,就自动加上了 \(\varphi(P)\) 。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int M=1e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
map<int,int>mp;
int n,P,q,a[M];
int nmo(int x,int p){
return x<p?x:(x%p+p);
}
int ksm(int x,int y,int pp){
int sum=1;
while(y){
if(y&1)sum=nmo(sum*x,pp);
x=nmo(x*x,pp);y>>=1;
}
return sum;
}
int getphi(int x){
int ans=1;
for(int i=2;i*i<=x;i++){
if(x%i)continue;
ans*=i-1;x/=i;
while(x%i==0)
ans*=i,x/=i;
}
if(x>1)ans*=x-1;
return ans;
}
int solve(int i,int r,int p){
if(i==r || p==1)return nmo(a[r],p);
int yp=(mp[p]?mp[p]:(mp[p]=getphi(p)));
return ksm(a[i],solve(i+1,r,yp),p);
}
signed main(){
n=read();P=read();
for(int i=1;i<=n;i++)a[i]=read();
q=read();
for(int i=1;i<=q;i++){
int l=read(),r=read();
printf("%lld\n",solve(l,r,P)%P);
}
return 0;
}

浙公网安备 33010602011771号