欧拉函数 笔记 2

莫比乌斯函数

大于 1 的正整数,只要有平方因子,那么其莫比乌斯函数值就为 0 。

f ( n ) = { 1                                 n = 1 ( − 1 ) r n        n = p 1 ∗ p 2 ∗ p 3 ∗ . . . ∗ p r 0                                    e l s e f(n)=\left\{ \begin{matrix} 1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n=1 \\ (-1)^r n~~~~~~n=p1*p2*p3*...*pr \\ 0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else \end{matrix}\right. f(n)= 1                               n=1(1)rn      n=p1p2p3...pr0                                  else

莫比乌斯函数是积性函数

莫比乌斯函数被称 μ ( n ) \mu(n) μ(n)

∑ d ∣ n μ ( d ) = [ n = 1 ] = \sum_{d|n}\mu(d)=[n=1]= dnμ(d)=[n=1]= { 1              n = 1 0                 e l s e \left\{ \begin{matrix} 1~~~~~~~~~~~~n=1 \\ 0 ~~~~~~~~~~~~~~~else \end{matrix}\right. {1            n=10               else

时间复杂度 O ( n ) O(\sqrt{n}) O(n )

莫比乌斯与欧拉

题目描述

给定 n n n, T T T,每次在区间 [ 1 , n ] [1,n] [1,n] 中选一个数 x x x,请输出 μ ( x ) μ(x) μ(x) ϕ ( x ) \phi(x) ϕ(x)

输入描述

第一行两个正整数 n , T n,T n,T ( 1 ≤ n , T ≤ 106 ) (1≤n,T≤106) (1n,T106)

接下来 T T T 行,每行两个整数 o p t , x ( 1 ≤ o p t ≤ 2 , 1 ≤ x ≤ n ) opt,x(1≤opt≤2,1≤x≤n) opt,x(1opt2,1xn),如果 o p t = 1 opt=1 opt=1,请输出 μ ( x ) μ(x) μ(x),否则请输出 ϕ ( x ) \phi(x) ϕ(x)

输出描述

如题

样例输入

10 5 1 4 2 7 1 7 2 3 2 9

样例输出

0 6 -1 2 6

#include
using namespace std;
long long ola[1000005],mu[1000005],prime[1000005],st[1000005];
int n,t,opt,x,cnt;
void fun(){
	mu[1]=1;
	st[1]=1;
	ola[1]=1;
	for(int i=1;i<=n;i++){
		if(!st[i]){
			prime[cnt++]=i;
			mu[i]=-1;
			ola[i]=i-1;
		}
		for(int j=0;j<cnt&&i*prime[j]<=n;j++){
			st[i*prime[j]]=1;
			if(i%prime[j]==0){
				mu[i*prime[j]]=0;
				ola[i*prime[j]]=ola[i]*prime[j];
				break;
			}
			mu[i*prime[j]]=-mu[i];
			ola[i*prime[j]]=ola[i]*ola[prime[j]];
		}
	}
}
int main(){
	scanf("%d%d",&n,&t); 
	fun();
	while(t--){
		scanf("%d%d",&opt,&x);
		if(opt==1){
			printf("%lld\n",mu[x]);
		}
		else{
			printf("%lld\n",ola[x]);
		}
	}
    return 0;
}

欧拉函数的性质

1.若n是素数, ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n1
2.若 n = p k , ϕ ( n ) = p k − p k − 1 n=p^{k},\phi(n)=p^{k}- p^{k-1} n=pk,ϕ(n)=pkpk1
3.若n是奇数, ϕ ( 2 n ) = ϕ ( n ) \phi(2n)=\phi(n) ϕ(2n)=ϕ(n)

欧拉定理

a ϕ ( m ) ≡ 1 ( m o d   m ) a^{\phi(m)}\equiv1(mod~m) aϕ(m)1(mod m)
a b ≡ a b   m o d   ϕ ( p ) ( m o d   p ) a^{b}\equiv a^{b~mod~\phi(p)}(mod~p) abab mod ϕ(p)(mod p)
a b ≡ { a b                                      b < ϕ ( m ) a ( b   m o d   ϕ ( m ) ) + ϕ ( m )                b ≤ ϕ ( m ) m o d    m a^b\equiv\left\{ \begin{matrix} a^{b}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~b<\phi(m) \\ a^{(b~mod~\phi(m))+\phi(m)} ~~~~~~~~~~~~~~b\le \phi(m) \end{matrix}\right. mod ~~m ab{ab                                    b<ϕ(m)a(b mod ϕ(m))+ϕ(m)              bϕ(m)mod  m

【模板】欧拉降幂

P5091 【模板】扩展欧拉定理

题目描述

求:
a b ( m o d   m ) a^b(mod~m) ab(mod m)

输入描述

三个正整数 a , m , b ( 1 ≤ a ≤ 109 , 1 ≤ m ≤ 108 , 1 ≤ b ≤ 1020000000 ) a,m,b(1≤a≤109,1≤m≤108,1≤b≤1020000000) a,m,b(1a109,1m108,1b1020000000)

输出描述

输出计算结果

样例1输入

2 7 4

样例1输出

2

样例2输入

998244353 12345 98765472103312450233333333333

样例2输出

5333

#include
using namespace std;
long long n,t,b,cnt,a,m;
string s;
long long downpow(long long phi){
	int len=s.size();
	long long x=0;
	bool flag=0;
	for(int i=0;i<len;i++){
		x=x*10+s[i]-'0';
		if(x>=phi){
			x%=phi;
			flag=1;
		}
	}
	if(flag){
		x+=phi;
	}
	return x;
}
long long ksm(long long k,long long o){
	long long ans=1;
	while(o){
		if(o&1){
			ans*=k;
			ans%=m;
		}
		o>>=1;
		k*=k;
		k%=m;
	}
	return ans;
}
long long fun(long long k){
	long long h=sqrt(k);
	long long ans=k;
	for(int i=2;i<=h;i++){
		if(k%i==0){
			ans=ans/i*(i-1);
			while(k%i==0){
				k/=i;
			}
		}
	}
	if(k>1){
		ans=ans/k*(k-1);
	}
	return ans;
}
int main(){
	scanf("%lld%lld",&a,&m);
	cin>>s;
	printf("%lld\n",ksm(a,downpow(fun(m))));
	
    return 0;
}

你可能感兴趣的:(笔记,c++)