学习笔记第十九节:BSGS&扩展BSGS

版权声明:因为我是蒟蒻,所以请大佬和神犇们不要转载(有坑)的文章,并指出问题,谢谢 https://blog.csdn.net/Deep_Kevin/article/details/83512195

正题

      BSGS,Baby Step Giant Step 。

      是用来解决类似于a^x\equiv b\ (\mod\ p),一类问题的。

      如果(a,p)=1,那么对于x>p-1,根据费马小定理a^{p-1}\equiv 1\ (\mod \ p),我们可以令x对p-1取mod,对答案没有影响,并且保证了答案在0\to p-2这个范围之内。

      我们可以令x=i*m-j,得到a^{i*m-j}\equiv b\ (\mod \ p)m=\sqrt p,i<=m,j<=m

      转移一下,得到a^{i*m}\equiv b*a^j\ (\mod \ p)

      我们把右式式处理出来放进一个std::map里面,然后让左式去找,找到的第一个就是答案。

void BSGS(){
	m=ceil(sqrt(double(p)));
	f[b]=0LL;
	for(int j=1;j<=m;j++){
		(b*=a)%=p;
		f[p]=j;
	}
	long long data=ksm(a,m),A=1;
	for(int i=1;i<=m;i++){
		(A*=data)%=p;
		if(f[A]){
			printf("%lld",i*m-f[A]);
			return ;
		}
	}
	printf("No solution");
}

      如果(a,p)\neq 1呢?

      这时候又要请出我们大名鼎鼎的扩展欧几里得解决问题了。

      我们先看一个式子:如果d\mid (a,p),a\equiv b(\mod \ p),那么\frac{a}{d} \ \equiv \frac{b}{d} (\mod \ \frac{p}{d})

      这个很显然,一移项就可以知道了。

      a^{x-k}\ * \frac{a^k}{\prod d} \equiv \frac{b}{\prod d}(\mod \frac{p}{\prod d} ),这时,经过不断得除以d,使得新的模数和a互质即可。

       然后,如果\frac{a^k}{\prod d}= \frac{b}{\prod d},只有一个解那就是x=k

       如果b不整除,那么没有解。

       最后,也是把\frac{a^k}{\prod d}看成一个常数,做一遍普通的BSGS

void exBSGS(){
	a=(a%p+p)%p;
	b=(b%p+p)%p;
	long long d,prod,k=0;
	while((d=gcd(a,p)!=1)){
		if(b%d==1) {printf("No solution");return ;}
		b/=d;p/=d;prod=prod*a/d%p;k++;
		if(b==k) {printf("%lld",k);return ;}
	}
	m=ceil(sqrt(double(p)));
	f[b]=0LL;
	for(int j=1;j<=m;j++){
		(b*=a)%=p;
		f[p]=j;
	}
	long long data=ksm(a,m),A=prod;
	for(int i=1;i<=m;i++){
		(A*=data)%=p;
		if(f[A]){
			printf("%lld",i*m-f[A]+k);
			return ;
		}
	}
	printf("No solution");
}

猜你喜欢

转载自blog.csdn.net/Deep_Kevin/article/details/83512195