大步小步算法模板题, poj2417

大步小步模板

(hash稍微有一点麻烦, poj不支持C++11略坑)

#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#define pb push_back
#define fi first
#define se second
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
LL A, B, P, phi, T;
const int MOD = 1e6+123456;

vector<PII> H[MOD+5];
LL qpow(LL a, LL b, LL P){
    LL ans = 1; for(; b; b >>= 1, (a*=a)%=P) if(b&1) (ans*=a)%=P; return ans;
}

inline void Hinsert(LL x, int v){ H[x%MOD].pb(mk(x, v)); }
inline void Herase(LL x) {  H[x%MOD].clear(); }
inline int Hfind(LL x){
    int u = x%MOD;
    for(int i = 0; i < H[u].size(); i++) if(H[u][i].fi == x) return H[u][i].se;
    return 0;
}

int main()
{
    while(scanf("%lld %lld %lld", &P, &A, &B) != EOF){
        phi = P-1;
        T = sqrt(phi+0.5);
        int i;
        LL At = A, AA;
        for(i = 1; i <= T; Hinsert(At*B%P, i), i++, (At*=A)%=P);
        AA = qpow(A, T, P); At = AA;
        for(i = 1; i*T <= P && !Hfind(At); i++, (At*=AA)%=P); //<=P 恰好可以覆盖0~P-1这些情况
        if(Hfind(At)){ printf("%lld\n", i*T - Hfind(At)); }
        else printf("no solution\n");
        for(At = A, i = 1; i <= T; Herase(At*B%P), i++, (At*=A)%=P);
    }
}

 

posted @ 2017-03-18 11:48  Saurus  阅读(223)  评论(0编辑  收藏  举报