• [模板] BSGS


    BSGS是一种解决一类专门的问题的解法,主要是解决已知A, B, C,求X使得A^x = B (mod p)这一类问题。

    解法很简单,先设x = i*m-j(m=ceil(sqrt(p))),然后进行变形,得到ai*m = b*aj (mod p)。

    先枚举j (范围0-m) ,将 b*aj  存入hash表。再枚举i (范围1-m) ,从hash表中寻找第一个满足ai*m = b*aj  (mod p)。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    map <ll,int> mp;
    ll t,m,n,ans,now;
    ll p,a,b;
    bool flag;
    ll qpow(ll a,ll b)
    {
        ll sum = 1;
        while(b)
        {
            if(b % 2 == 1)
            {
                sum *= a;
            }
            a *= a;
            sum %= p;
            a %= p;
            b >>= 1;
        }
        return sum;
    }
    int main()
    {
        while(~scanf("%lld%lld%lld",&p,&a,&b))
        {
            if(a % p == 0)
            {
                printf("no solution
    ");
                continue;
            }
            mp.clear();
            m = ceil(sqrt(p));
            flag = false;
            now = b % p;
            mp[now] = 0;
            for(int i = 1;i <= m;i++)
            {
                now = (now * a) % p;
                mp[now] = i;
            }
            t = qpow(a,m);
            now = 1;
            duke(i,1,m)
            {
                now = (now * t) % p;
                if(mp[now])
                {
                    flag = true;
                    ans = i * m - mp[now];
                    printf("%lld
    ",(ans % p + p) % p);
                    break;
                }
            }
            if(!flag)
            printf("no solution
    ");
        }
        return 0;
    }
  • 相关阅读:
    @codeforces
    @codeforces
    @hdu
    @hdu
    @bzoj
    @bzoj
    @topcoder
    推荐系统主题相关资料
    Python统计百分比及排序
    如何发布及部署asp.net网站
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9955304.html
Copyright © 2020-2023  润新知