1. 程式人生 > >洛谷【數競黨出的數論賽】U46278 按鈕

洛谷【數競黨出的數論賽】U46278 按鈕

傳送門

大膽猜結論:k^x≡1 mod m,答案就是最小正x

直接EXBSGS套上,明顯最小解為0,所以答案是次小解,雖然我總覺得我的是錯的但它就是過了……

EXBSGS盜的某位大爺的板

#include<math.h>
#include<stdio.h>
#include<string.h>
#include <iostream>
#include<algorithm>
#define N 140142
using namespace std;
typedef long long ll;
struct Hash_Set
{
    ll head[N], next[N], X[N], val[N], tot;
    void clear()
    {
        memset(head, 0, sizeof(head));
        memset(next, 0, sizeof(next));
        memset(val, -1, sizeof(val));
        memset(X, 0, sizeof(X));
        tot = 0;
    }
    ll& operator [](ll x)
    {
        ll index = x%N;
        for (ll i = head[index]; i; i = next[i])
        {
            if (X[i] == x)
                return val[i];
        }
        next[++tot] = head[index];
        head[index] = tot;
        X[tot] = x;
        return val[tot];
    }
}hash;
ll pow(ll x, ll y, ll mod)
{
    ll ret = 1;
    while (y)
    {
        if (y & 1)
            ret = ret*x%mod;
        x = x*x%mod;
        y >>= 1;
    }
    return ret;
}
ll gcd(ll a, ll b)
{
    ll t = a%b;
    while (t)
    {
        a = b, b = t;
        t = a%b;
    }
    return b;
}
void exgcd(ll a, ll b, ll &x, ll &y)
{
    if (!b)
        x = 1, y = 0;
    else
    {
        exgcd(b, a%b, y, x);
        y -= a / b*x;
    }
}
ll inv(ll t, ll mod)
{
    ll x, y;
    exgcd(t, mod, x, y);
    return (x%mod + mod) % mod;
}
ll BSGS(ll A, ll B, ll C)
{
    hash.clear();
    ll bk = ceil(sqrt(C)), i, j, k, D, temp;
    for (i = 0, D = 1; i < bk; i++, D = D*A%C)
    {
        if (hash[D] == -1)
            hash[D] = i;
    }
    temp = inv(D, C);
    bool fg = 0;
    for (i = 0, k = B; i <= bk; i++, k = k*temp%C)
    {
        if (hash[k] != -1) {
        	if(!fg) {
        		fg = 1;
        	}
        	else return i*bk + hash[k];
        }
            
    }
    return -1;
}
ll EXBSGS(ll A, ll B, ll C)
{
    if(C==1)
    {
        if(!B)  return 0;
        else    return -1;
    }
    ll lg = ceil(log(C*1.0) / log(2)), i, k, mod;
    for (i = 0, k = 1; i <= lg; i++, k = k*A%C);
    i = 0, mod = C;
    while ((k = gcd(A, mod)) != 1)
    {
        if (B%k)    return -1;
        B /= k, mod /= k;
        i++;
    }
    ll ret = BSGS(A, B*inv(pow(A, i, mod)*inv(C / mod, mod) % mod, mod) % mod, mod);
    if (ret != -1)
        return ret + i;
    else
        return -1;
}
int main()
{
    ll A, C;
    cin >> C >> A;
    ll ans = EXBSGS(A, 1, C);
    if(ans >= 0) cout << ans;
    else puts("Let's go Blue Jays!");
    return 0;
}