MITE:欧拉欧拉欧拉欧拉(beta)

6 篇文章 0 订阅

你们要的欧拉欧拉欧拉欧拉终于来了

欧拉函数

欧拉含树

我们用 φ(n)来表示欧拉函数
它等于<=n的数中与n互质的数的数目(1姑且认为与任何数互质吧)

首先当然是大家都擅长的暴力了,我们知道,两个数互质就是gcd=1,所以就有

int phi(int n)
{
   int ans=0;
   for(int i=1;i<=n;i++)
   	if(gcd(i,n)==1)
   		ans++;
   return n;
}

但是很多时候暴力是出不了奇迹的,所以我们需要更好的方法

很多时候我们思考问题要学会逆向思维,只要把不与n互质的数去掉的话剩下的不就是与n互质的了。还记得之前说过的定理吗,在讲线筛的时候,任何合数都能拆成n个素数的乘积。所以只要把小于n的n的所有素因数的倍数去掉就好啦,是不是很简单哇。具体做法就算简单容斥啦(此时,我终于想起了没有做容斥的博客,但是问题不大)

比如说24,它的素因数有2,3
小于等于24&&2的倍数:24/2=12
小于等于24&&3的倍数:24/3=8
2和3的倍数24/(2 * 3)
需要去除的数为24 *(1/2-1/6+1/3)
φ(24)=24(1-1/2-1/3+1/6)=24(1-1/2)(1-1/3)=8

再比如三个素数的2*3*5=30
φ(30)=30(1-1/2)(1-1/3)(1-1/5)=8

至于为什么具体转到容斥定理(还没写)

于是我们就可以有新的写法了

int phi(int n)
{
	int ans=n;
	for(int i=2;i*i<=n;i++)
	{
		//由于任何一个合数都至少有一个不大于根号n的素因子,所以只需遍历到根号n即可
		if(n%i==0)
		{
			ans = ans/i*(i-1);
			//防溢出
			while(n%i==0)n/=i;
			//使n的因子没有素数i的倍数
		}
	}
	if(n>1)
		ans=ans/n*(n-1);
	//如果n最终是素数的话会跳出循环,没有计算,所以这里还要再判断一次
	return ans;
}

聪明的同学们可能已经发现了,这东西是可以打表的
遍历一遍,只要遍历到素数的话它的所有倍数(包括它本身)都除以它乘它-1既/i*(i-1)

int phi[N];
void Euler()
{
	phi[1]=1;
	for(int i=2;i<N;i++)
	{
		if(phi[i])
		{
			for(int j=i;j<N;j+=i)
			{
				if(!phi[j]) phi[j]=j;
				phi[j]=phi[j]/i*(i-1);
			}
		}
	}
}

复杂度和埃筛差不多,O(nlnln n)

然后提一下欧拉函数的一些性质
1.若p为质数,φ ( p)=p-1

因为小于质数p的数都与p互质

2.若i mod p = 0,且p为质数,则φ( i * p ) = φ(i) *p

ϕ ( i ) = i ∗ ( 1 − 1 a ) ∗ ( 1 − 1 p ) \phi(i)=i*(1-\frac{1}{a})*(1-\frac{1}{p}) ϕ(i)=i(1a1)(1p1)

ϕ ( i ∗ p ) = i ∗ p ∗ ( 1 − 1 a ) ∗ ( 1 − 1 p ) = ϕ ( i ) ∗ p \phi(i*p)=i*p*(1-\frac{1}{a})*(1-\frac{1}{p})=\phi(i)*p ϕ(ip)=ip(1a1)(1p1)=ϕ(i)p

3.若i mod p ≠0,且p为质数, 那么 φ( i * p )=φ(i) * ( p-1 )

ϕ ( i ) = i ∗ ( 1 − 1 a ) ∗ ( 1 − 1 b ) \phi(i)=i*(1-\frac{1}{a})*(1-\frac{1}{b}) ϕ(i)=i(1a1)(1b1)

ϕ ( i ∗ p ) = i ∗ p ∗ ( 1 − 1 a ) ∗ ( 1 − 1 b ) ∗ ( 1 − 1 p ) = i ∗ ( 1 − 1 a ) ∗ ( 1 − 1 b ) ∗ ( p − 1 ) = ϕ ( i ) ∗ ( p − 1 ) \phi(i*p)=i*p*(1-\frac{1}{a})*(1-\frac{1}{b})*(1-\frac{1}{p})=i*(1-\frac{1}{a})*(1-\frac{1}{b})*(p-1)=\phi(i)*(p-1) ϕ(ip)=ip(1a1)(1b1)(1p1)=i(1a1)(1b1)(p1)=ϕ(i)(p1)

4.对于n=p^k ,有 ϕ ( n ) = ( p − 1 ) ∗ p k − 1 \phi(n)=(p-1) * p^{k-1} ϕ(n)=(p1)pk1

ϕ ( n ) = ϕ ( p k − 1 ∗ p ) = ϕ ( p k − 1 ) ∗ p = . . . = ϕ ( p ) ∗ p k − 1 = ( p − 1 ) ∗ p k − 1 \phi(n)=\phi(p^{k-1}*p)=\phi(p^{k-1})*p=...=\phi(p)*p^{k-1}=(p-1)*p^{k-1} ϕ(n)=ϕ(pk1p)=ϕ(pk1)p=...=ϕ(p)pk1=(p1)pk1

5.若gcd(n,m)=1, ϕ ( n ∗ m ) = ϕ ( n ) ∗ ϕ ( m ) \phi(n * m)=\phi(n) * \phi(m) ϕ(nm)=ϕ(n)ϕ(m)

n与m互质,质数互不相同

6. n = ∏ p i k i n=\prod p_i^{k_i} n=piki ,则有 ϕ ( n ) = n ∗ ∏ ( 1 − 1 p i ) \phi(n)=n * \prod (1-\frac{1}{p_i}) ϕ(n)=n(1pi1)

p为质数,易得(真的易得吖)

7.若gcd(a,m)=1,则 a ϕ ( m ) ≡ 1 a^{\phi(m)} \equiv 1 aϕ(m)1 (mod m)

欧拉定理,下有证明

8.小于n且与n互质的数的和 S=n* ϕ ( n ) 2 \frac{\phi(n)}{2} 2ϕ(n);

易知,若i与n互质,则n-i与n也互质

若i与n不互质 gcd(i,n)=a > 0, (n-i)/a=n/a-i/a为整数,故a也为n-i的因数,故 gcd(n,n-i) != 1

所以有S = n* ϕ ( n ) 2 \frac{\phi(n)}{2} 2ϕ(n)

     ∑ i = d ∣ n ϕ ( d ) \ \ \ \ \sum_{i=d|n}{\phi(d)}     i=dnϕ(d)=n

ϕ ( n ) = ∑ d ∣ n μ ( d ) ∗ n d \phi(n)=\sum_{d|n}\mu(d)*\frac{n}{d} ϕ(n)=dnμ(d)dn

由性质1 2 3 可得一种更快得筛法

const int N = 1e6+10;
int phi[N],prime[N];
int tot;
void Euler()
{
	phi[1] = 1;
	for(int i = 2; i < N;i++)
	{
		if(!phi[i])
		{
			phi[i]=i-1;
			prime[tot++];
		}
		for(int j=0;j<tot&&1ll*i*prime[j]<N;j++)
		{
			if(i%prime[j])
				phi[i*prime[j]]=phi[i]*(prime[j]-1);
			else
			{
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
		}
	}
}

原理和线筛差不多就不多累赘了

欧拉定理

当a,m互质时, a ϕ ( m ) ≡ 1 ( m o d   m ) a^{\phi(m)}\equiv1 (mod\ m) aϕ(m)1(mod m)

枚举小于m与m互质的数 x 1 , x 2 , . . . , x ϕ ( m ) x_1,x_2,...,x_{\phi(m)} x1,x2,...,xϕ(m)

p i = a ∗ x i p_i=a*x_i pi=axi

则对于 i ! = j , 有 p i   m o d   m   ! =   p j   m o d   m i!=j ,有 p_i \ mod \ m \ != \ p_j \ mod \ m i!=j,pi mod m != pj mod m

$ p_i-p_j=a(x_i-x_j)$

因为a与m互质, x i x_i xi与m互质,所以 a ( x i − x j ) a(x_i-x_j) a(xixj)与m互质

( p i − p j ) m o d   m ! = 0 (p_i-p_j)mod\ m !=0 (pipj)mod m!=0

所以有 p i   m o d   m   ! =   p j   m o d   m p_i \ mod \ m \ != \ p_j \ mod \ m pi mod m != pj mod m

因此,对于确定的i,有确定的j使 p i m o d &ThinSpace;&ThinSpace;   m = x j p_i \mod\ m = x_j pimod m=xj

且i对j是一一映射的

因此得 ∏ i = 1 ϕ ( m ) p i ≡ ∏ i = 1 ϕ ( m ) a ∗ x i ≡ a ϕ ( m ) ∗ ∏ i = 1 n x i ≡ ∏ i = 1 n x i ( m o d   m ) \prod_{i=1}^{\phi(m)}p_i\equiv\prod_{i=1}^{\phi(m)}a*x_i\equiv a^{\phi(m)}*\prod_{i=1}^{n}x_i\equiv \prod_{i=1}^{n}x_i (mod\ m) i=1ϕ(m)pii=1ϕ(m)axiaϕ(m)i=1nxii=1nxi(mod m)

得证 a ϕ ( m ) ≡ 1 ( m o d   m ) a^{\phi(m)}\equiv 1(mod\ m) aϕ(m)1(mod m)

拓展欧拉定理

a c ≡ { a c   m o d   ϕ ( m )             ,   g c d ( a , m ) = 1 a c                           ,   g c d ( a , m ) ! = 1 , c &lt; ϕ ( m ) a c   m o d   ϕ ( m ) + ϕ ( m )     ,   g c d ( a , m ) ! = 1 , c &gt; ϕ ( m )       ( m o d   m ) a^c \equiv\begin{cases} a^{c \ mod\ \phi(m)} \ \ \ \ \ \ \ \ \ \ \ ,\ gcd(a,m)=1\\ a^c\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ,\ gcd(a,m)!=1,c&lt;\phi(m)\\ a^{c\ mod\ \phi(m)+\phi(m)}\ \ \ ,\ gcd(a,m)!=1,c&gt;\phi(m)\end{cases} \ \ \ \ \ (mod\ m) acac mod ϕ(m)           , gcd(a,m)=1ac                         , gcd(a,m)!=1,c<ϕ(m)ac mod ϕ(m)+ϕ(m)   , gcd(a,m)!=1,c>ϕ(m)     (mod m)

证明有缘的话会给出来的(咕咕咕)

看了这个后就不要再写出 a c ≡ ( a   m o d   p ) c   m o d   p a^c \equiv (a\ mod\ p)^{c\ mod\ p} ac(a mod p)c mod p(mod m)这种东西来了,这个是错的错的错的

欧拉降幂

就是当指数爆炸(超64位整数,几百位甚至更多)时可以用拓展欧拉定理来处理c mod ϕ ( m ) \phi(m) ϕ(m)

int main()
{
	ll a,c,p;
	char b[100000];
	cin>>a>>b>>p;
	int l = strlen(b);
	for(int i=0;i<l;i++)
		c=(c*10+b[i]-'0')%p;
	cout<<qpow(a,c%phi(p)+phi(p),p)<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值