扩展BABT STEP hdu 2815 poj 3243

来源:互联网 发布:优化win10字体 编辑:程序博客网 时间:2024/04/29 04:16

       http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4       这里已经说的很清楚了

        A^X  = B MOD(C)               若   gcd(A,C)!=1   令 d = gcd(A,C)  B/=d, C/=d  重复此过程  我们得到  d1,d2,d3,d4...............dk;   

     我们得到   令       P = d1*d2*d3.......*dk;                A'=A^k/P,    B‘=B/P          C'   = C/P;                A^(X-k)*A'  =  B'  mod( C'   )  此为 已经是 普通情况的 BABY STEP 了 


HDU 2815 

#include<cstdio>#include<cstring>#include<algorithm>#include<numeric>#include<vector>#include<string>#include<set>#include<iostream>#include<map>#include<cmath>#include<queue>using namespace std;typedef long long ll;const int maxn = 71111;const int mod = 77777;const int hash_size =  87719;template<typename T>T gcd(T a,T b){    return b?gcd(b,a%b):a;}struct node {    ll key;    int val, next;    node() {    }    node(ll key, int val, int next) :            key(key), val(val), next(next) {    }};struct HashMap {    node edge[hash_size << 2];    int i, E;    int head[hash_size + 10];    void init() {        E = 0;        memset(head, -1, sizeof(head));    }    bool insert(ll key, int val) {        int u;        u = key % hash_size;        for (i = head[u]; ~i; i = edge[i].next) {            if (edge[i].key == key)                return false;        }        edge[E] = node(key, val, head[u]);        head[u] = E++;        return true;    }    int find(ll key) {        int u = key % hash_size;        for (i = head[u]; ~i; i = edge[i].next) {            if (edge[i].key == key)                return edge[i].val;        }        return -1;    }};HashMap Hash;ll exgcd(ll a, ll b, ll &x, ll &y) {    if (!b) {        x = 1;        y = 0;        return a;    }    ll d = exgcd(b, a % b, x, y);    ll t = x;    x = y;    y = t - (a / b) * y;    return d;}ll remain[100];ll go(ll A, ll B, ll C) {    if(B>=C) return -1;    if(B==1) return 0;    ll D=1,d,t=1;    int i,cnt=0;    for(i=0;i<=100;t=t*A%C,++i)    {        if(t==B) return i;    }    while((d=gcd(A,C))!=1)    {        if(B%d) return -1;        cnt++;        B/=d;        C/=d;        D=D*(A/d)%C;    }    int m=(int)ceil(sqrt(C+0.0));    //map<ll,int>mp;    t=1;    Hash.init();    for(i=1;i<=m;++i)    {        t=t*A%C;        Hash.insert(t,i);    }    ll x,y;    //cout<<A<<" "<<B<<" "<<C<<endl;    for(i=0;i<=m;D=D*t%C,++i)    {        exgcd(D,C,x,y);        x*=B;        x=(x%C+C)%C;        y=Hash.find(x);        if(~y)            return 1ll*i*m+y+cnt;    }    return -1;}int main() {    ios::sync_with_stdio(false);    ll K, P, N;    //freopen("D:\\test.in","r",stdin);    //freopen("D:\\test1.in","w",stdout);    while (~scanf("%I64d%I64d%I64d", &K, &P, &N)) {        ll ans=go(K,N,P);        if (~ans)            printf("%I64d\n", ans);        else            puts("Orz,I can’t find D!");    }    return 0;}

 

poj 3243 

#include<cstdio>#include<cstring>#include<algorithm>#include<numeric>#include<vector>#include<string>#include<set>#include<iostream>#include<map>#include<cmath>#include<queue>using namespace std;typedef long long ll;const int maxn = 71111;const int mod = 77777;const int hash_size = 87719;template<typename T>T gcd(T a, T b) {return b ? gcd(b, a % b) : a;}struct node {ll key;int val, next;node() {}node(ll key, int val, int next) :key(key), val(val), next(next) {}};struct HashMap {node edge[hash_size << 2];int i, E;int head[hash_size + 10];void init() {E = 0;memset(head, -1, sizeof(head));}bool insert(ll key, int val) {int u;u = key % hash_size;for (i = head[u]; ~i; i = edge[i].next) {if (edge[i].key == key)return false;}edge[E] = node(key, val, head[u]);head[u] = E++;return true;}int find(ll key) {int u = key % hash_size;for (i = head[u]; ~i; i = edge[i].next) {if (edge[i].key == key)return edge[i].val;}return -1;}};HashMap Hash;ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1;y = 0;return a;}ll d = exgcd(b, a % b, x, y);ll t = x;x = y;y = t - (a / b) * y;return d;}ll remain[100];ll go(ll A, ll B, ll C) {if (B >= C)B%=C;if (B == 1)return 0;ll D = 1, d, t = 1;int i, cnt = 0;for (i = 0; i <= 100; t = t * A % C, ++i) {if (t == B)return i;}while ((d = gcd(A, C)) != 1) {if (B % d)return -1;cnt++;B /= d;C /= d;D = D * (A / d) % C;}int m = (int) ceil(sqrt(C + 0.0));//map<ll,int>mp;t = 1;Hash.init();for (i = 1; i <= m; ++i) {t = t * A % C;Hash.insert(t, i);}ll x, y;for (i = 0; i <= m; D = D * t % C, ++i) {exgcd(D, C, x, y);x *= B;x = (x % C + C) % C;y = Hash.find(x);if (~y)return 1ll * i * m + y + cnt;}return -1;}int main() {ios::sync_with_stdio(false);ll K, P, N;while (~scanf("%I64d%I64d%I64d", &K, &P, &N) && (K | P | N)) {ll ans = go(K, N, P);if (~ans)printf("%I64d\n", ans);elseputs("No Solution");}return 0;}