Discrete Logging poj-2417

    题目大意:求$a^x\equiv b(mod\qquad c)$

    注释:O(分块可过)

      想法:介绍一种算法BSGS(Baby-Step Giant-Step),网上大佬说拔山盖世qwq

        算法是这样的(贼难受,所以手写了)

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> 
#include <map>
using namespace std;
typedef long long ll;
ll a,b,c,m,f[10000000];
map<ll,int> mp;
ll quick_power(ll x)
{
	ll sum=1;
	ll mid=a;
	while(x)
	{
		if(x&1) sum=sum*mid%c;
		x>>=1;
		mid=(mid*mid)%c;
	}
	return sum;
}
int main()
{
	mp.clear();
	while(scanf("%I64d%I64d%I64d",&c,&a,&b)!=EOF)
	{
		mp.clear();
		if(a%c==0) //判断a,c 是否互质,因为c 是质数,所以直接判断是否整除即可
		{
			printf("no solution\n");
			continue;
		}
		int p=false;
		float akkk=(float)c;
		m=ceil(sqrt(akkk));
		ll ans=b%c;
		mp[ans]=0;
		for(int i=1;i<=m;i++)//拔山过程(Baby-Step)
		{
			ans=(ans*a)%c;
			mp[ans]=i;
		}
		ll t=quick_power(m); ans=1;
		for (int i=1;i<=m;i++)//盖世过程(Giant-Step)
		{
			ans=(ans*t)%c;
			if (mp[ans])
			{
				int t=i*m-mp[ans];
				printf("%I64d\n",(t%c+c)%c);
				p=true;
				break;
			}
		}
		if (!p) 
		printf("no solution\n");
	}
}

     小结:可以优化我之前写过的一些东西,感觉挺有用的。

        这东西想一想就知道特判贼tm多