zoukankan      html  css  js  c++  java
  • Discrete Logging ZOJ

    就是求Ax三B(mod C)当C为素数时

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int MAXINT = ((1 << 30) - 1) * 2 + 1;
    
    int A, B, C;
    struct Hashmap //哈希表代替map
    {
        static const int Ha = 999917, maxe = 46340;
        int E, lnk[Ha], son[maxe + 5], nxt[maxe + 5], w[maxe + 5];
        int top, stk[maxe + 5];
        void clear() { E = 0; while (top) lnk[stk[top--]] = 0; }
        void Add(int x, int y) { son[++E] = y; nxt[E] = lnk[x]; w[E] = MAXINT; lnk[x] = E; }
        bool count(int y)
        {
            int x = y%Ha;
            for (int j = lnk[x]; j; j = nxt[j])
            if (y == son[j]) return true;
            return false;
        }
        int& operator [] (int y)
        {
            int x = y%Ha;
            for (int j = lnk[x]; j; j = nxt[j])
            if (y == son[j]) return w[j];
            Add(x, y); stk[++top] = x; return w[E];
        }
    };
    Hashmap f;
    
    int exgcd(int a, int b, int &x, int &y)
    {
        if (!b) { x = 1; y = 0; return a; }
        int r = exgcd(b, a%b, x, y), t = x; x = y; y = t - a / b*y;
        return r;
    }
    int BSGS(int A, int B, int C)
    {
        if (C == 1) if (!B) return A != 1; else return -1;
        if (B == 1) if (A) return 0; else return -1;
        if (A%C == 0) if (!B) return 1; else return -1; //几种特判
        int m = ceil(sqrt(C)), D = 1, Base = 1; f.clear();
        for (int i = 0; i <= m - 1; i++) //先把A^j存进哈希表
        {
            f[Base] = min(f[Base], i);
            Base = ((LL)Base*A) % C;
        }
        for (int i = 0; i <= m - 1; i++)
        {
            int x, y, r = exgcd(D, C, x, y);
            x = ((LL)x*B%C + C) % C; //扩欧求A^j
            if (f.count(x)) return i*m + f[x]; //找到了
            D = ((LL)D*Base) % C;
        }
        return -1;
    }
    int main()
    {
        while (~scanf("%d%d%d", &C, &A, &B))
        {
            int ans = BSGS(A, B, C);
            if (ans == -1) printf("no solution
    "); else
                printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    uni-app 开发 app
    小程序上传图片到腾讯云
    前端上传文件到腾讯云
    小程序中 使用 aes 进行加密解密处理
    查询端口被占用并且结束占用的端口
    js 对象根据 id 删除一条数据
    element-ui 组件改变样式
    element-ui 弹出框在遮罩层下面
    css样式穿透
    css 清除浮动
  • 原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/9997985.html
Copyright © 2011-2022 走看看