zoukankan      html  css  js  c++  java
  • BZOJ3122 随机数生成器——BSGS

    题意

    链接

    给定 $p, a, b, x_1$,现有一数列

    $$x_{i+1} equiv (ax_i + b) mod p$$

    求最小的 $i$ 满足 $x_i = t$

    分析

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    //ax + by = d,且|x|+|y|最小,其中d=gcd(a,b)
    //即使a, b在int范围内,x和y也有可能超过int范围
    void exgcd(ll a, ll b, ll &d, ll &x, ll &y)
    {
        if (!b){ d = a; x = 1; y = 0;}
        else{ exgcd(b, a % b, d, y, x); y -= x * (a / b);}
    }
    
    //计算模n下a的逆。如果不存在逆,返回-1
    //ax=1(mod n)
    ll inv(ll a, ll n)
    {
        ll d, x, y;
        exgcd(a, n, d, x, y);
        return d == 1 ? (x + n) % n : -1;
    }
    
    inline ll bsgs(ll a, ll b, ll p) {
        a %= p;
        b %= p;
        std::map<ll, ll> map;
        ll m = ceil(sqrt(p)), t = 1;
        for (int i = 0; i < m; i++) {
            if (!map.count(t)) map[t] = i;
            t = t * a % p;
        }
    
        ll k = inv(t, p), w = b;
        for (int i = 0; i < m; i++) {
            if (map.count(w)) return i * m + map[w];
            w = w * k % p;
        }
    
        return -1;
    }
    
    inline ll solve(ll p, ll a, ll b, ll x1, ll t) {
        if (t == x1) return 1;
        else if (a == 0) return b == t ? 2 : -1;
        else if (a == 1) {
            if (!b) return -1;
            return ((((t - x1) % p + p) % p) * inv(b, p) % p) + 1;
        } else {
            ll q = inv(1 - a + p, p);
            ll d = (((t - b * q) % p + p) % p) * inv(((x1 - b * q) % p + p) % p, p);
            ll ans = bsgs(a, d, p);
            if (ans == -1) return -1;
            else return ans + 1;
        }
    }
    
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            int p, a, b, x1, t;
            scanf("%d %d %d %d %d", &p, &a, &b, &x1, &t);
            printf("%lld
    ", solve(p, a, b, x1, t));
        }
    }

    发现BZOJ还能下测试数据:https://darkbzoj.tk/data/

    参考链接:https://oi.men.ci/sdoi2013-random/

  • 相关阅读:
    数据库期末考试复习
    函数 初识
    文件操作
    深浅copy 和 集合
    数据编码补充
    字典的增删改查和嵌套
    面试题 和 python 2与3的期区别
    英文练习
    初识数据类型
    测试基础-系统测试(2)
  • 原文地址:https://www.cnblogs.com/lfri/p/11269473.html
Copyright © 2011-2022 走看看