acm训练 18.12.1 B - 2^x mod n = 1

B - 2^x mod n = 1


一、题目

输入一个n,来寻找一个最小的x,使得2^ x mod n = 1 成立,并输出2^ x mod n = 1 。
若不存在这样的x,则输出2^? mod n = 1。

例如:
当n=2时,不存在x满足条件,则输出2^? mod 2 = 1。
当n=5时,可以找到最小的x=4,所以输出2^4 mod 5 = 1。


二、思路

首先会想到的应该是暴力模拟了,写一个循环,来寻找x。当然,不可能无限的找下去,因为存在不存在x的情况,并且还会出现 tle 的情况,所以这个方法不可行。

但在没有其他方法解决的时候,只能硬着头皮上了。这个循环的代码很容易写出来,但还是有需要注意的地方。
因为x可能会特别的大,而2^x会成指数级的增长,因此我们需要在运算过程中对2 ^x进行取余,即每当乘2时都需要mod n,以确保2 ^x 不会炸掉,并且对最后的结果没有产生影响。


三、代码

#include<stdio.h>
int main()
{
	long i,n,p;
	while(scanf("%d",&n)!=EOF)
	{
 	p=2;
 	for (i=1;i<=1000000;++i)
 	{
		p=p*2%n;
 		if (p==1) break;
	} 
 	if (i<=1000000) printf("2^%d mod %d = 1\n",i+1,n);
 	else printf("2^? mod %d = 1\n",n);
	}
	return 0;
} 

这个代码a了本题,但讨论还没有结束!


四、缺陷

很明显,我们不能确定 i 的循环范围。
首先我们假设当循环 10^7 次是时会 tle,输出的结果需要 10^5 次,那当 i 小于10^5时会WA,大于 10^7会 tle ,那么 i 的范围就是 10^ 7到10^ 5。但是数据并不一定想象的那样,随着 n 的增大, i 的循环范围与需要加大,所以可以AC的范围会越来越小,直到不存在这种范围,即10^7 以下全WA,10^7 以上全tle,所以我们需要找到一种更优的算法,来解决这个问题!


五、费马-欧拉定理

关于如何优化,我们先来看看一个定理——费马-欧拉定理
对于互质的两个数a,p,存在这样一个等式

aφ(p) ≡ 1(mod p)
其中φ(p)是1 到 p-1当中与 p 互质的数的个数


六、优化

题目中a为2,所以所有的奇数都与a互质,而偶数不行,因此当输入的n为偶数是一定不行,而后我们只需求奇数的结果。(特例:当n=1时也不行哦)
从而避免了WA的情况!但tle还没避免!


七、小结

我曾考虑过试图求φ(p)的值当作结果,但出现的问题!

当n=7时,求得φ(n)=6,虽然x=6可以时等式成立,但并不是最优解,因为x=3时也可以使等式成立!

所以如何避免tle还在考虑中!


未完待续ing。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值