poj_2417 (baby_step,giant_step算法)

最近要把大工的线段树专题补完,然后写一个线段树的总结。。。 

http://blog.csdn.net/ACM_cxlove?viewmode=contents 附上cxlove大神的博客,这里面已经讲的很明白了。

感觉baby_step,giant_step算法比较好理解,暴力的复杂度被优化到了o(sqrt(n)),然后匹配的复杂度,我是用set写的,复杂度就是o(sqrt(n)*log(sqrt(n)))。

下面直接附上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#define FOR(i,x,y)  for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define ll long long

using namespace std;

typedef pair<ll,int> pii;
ll p,b,n,m,num[1<<16],x,y;

ll quickpow(ll a,ll n,ll m){
    ll ans=1;
    while(n){
        if(n&1) ans = (ans*a)%m;
        a = (a*a)%m;
        n>>=1;
    }
    return ans;
}
int main()
{
    //freopen("test.in","r",stdin);
    while(~scanf("%I64d%I64d%I64d",&p,&b,&n)){
        map <ll,int> s;
        set <ll> q;
        m = (ll)sqrt(1.0*p)+1;
        num[0] = 1;
        q.insert(num[0]);
        s[num[0]] = 0;
        FOR(i,1,m){
            num[i] = num[i-1]*b;
            num[i] %= p;
            q.insert(num[i]);
            s.insert(pair<ll,int> (num[i],i));
        }
        bool flag = false;
        FOR(i,0,m){
            ll temp = p-1-i*m;
            if(temp < 0)    break;
            temp = quickpow(b,temp,p);
            temp = (temp*n)%p;
            set <ll>::iterator it;
            it = q.find(temp);
            if(it != q.end()){
                y = (*it);
                y = s[y];
                x = i;
                flag = true;
                break;
            }
        }
        if(!flag)   printf("no solution\n");
        else printf("%I64d\n",x*m+y);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/hqwhqwhq/p/4811899.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值