50分求改(改90分就行)给关注,谢谢。
查看原帖
50分求改(改90分就行)给关注,谢谢。
97737
Wsyflying2022楼主2022/2/18 20:43
#include <bits/stdc++.h>
#define int long long
using namespace std;
int p;
inline int fastpow(int x,int t) {
	int base=x,res=1;
	while (t) {
		if (t & 1) 
			res=res*base%p;
		base=base*base%p;
		t>>=1;	
	}
	return res;
}
inline int bsgs(int a,int b) {
	int t=ceil(sqrt(p));
	unordered_map <int,int> hash;
	hash.clear();
	for (int i=0;i<t;i++) 
	    hash[b*fastpow(a,i)%p]=i;
	a=fastpow(a,t)%p;
	for (int i=0;i<=t;i++){
		int val=fastpow(a,i)%p;
		int pos=hash.find(val)==hash.end() ? -1 : hash[val];
		if (i*t-pos>=0 && pos>=0) return i*t-pos;
	}
	return -1;
}
inline void exbsgs(int a,int b) {
	int g=__gcd(a,p),cnt=0,tmp=1;
	while (g!=1) {
		if (b%g) {
			printf("No Solution\n");
			return ;
		}
		cnt++,b/=g,p/=g,tmp=tmp*(a/g)%p;
		if (b==tmp){
			printf("%d\n",cnt);
			return ;
		}
		g=__gcd(a,p);
	}
	b=b%p*(fastpow(tmp,p-2)%p+p)%p;
	int ans=bsgs(a,b);
	if (ans==-1) 
		printf("No Solution\n");
	else printf("%d\n",(ans+cnt)%p);
}
signed main(){
	while (true) {
		int a,b;
		scanf("%lld%lld%lld",&a,&p,&b);
		if (a==0 && p==0 && b==0) break;
		if (a==0 && b==0) {
			printf("0\n");
			continue;
		}
		if (a==0) {
			printf("No Solution\n");
			continue;
		}
		if (b==0 || p==0) {
			printf("1\n");
			continue;
		}
		if (b==0 && p==0) {
			printf("No Solution\n");
			continue;
		}
		exbsgs(a,b);
	}
	return 0;
}

2022/2/18 20:43
加载中...