码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2013] 随机数生成器 题解

时间:2020-10-27 11:37:40      阅读:17      评论:0      收藏:0      [点我收藏+]

标签:map   putc   span   putchar   out   bit   pre   ==   get   

Description

给你 \(p,a,b,x_1,t\),定义数列 \(\{x\}:x_i=ax_{i-1}+b\space (x\ge2)\),求最小使 \(x_n=t\)\(n\)

\(0\le a,b,x_1,t < p\le 10^9\)

Sol

转化为等比数列求和:

\[x_{i+1}= a\times x_i+b \]

\[x_{i+1}+\frac b{a-1}=a\times x_i+\frac{ab}{a-1} \]

\[x_{i+1}+\frac b{a-1}=a(x_i+\frac{b}{a-1}) \]

\[x_n+\frac b{a-1}=a^{n-1}(x_1+\frac{b}{a-1}) \]

\[a^{n-1}\equiv \frac{(a-1)x_n+b}{(a-1)x_1+b} \]

跑 BSGS 即可。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int Read() {
    int x = 0, f = 1; char ch = getchar();
    while(!isdigit(ch))  {if(ch == ‘-‘)  f = -1; ch = getchar();}
    while(isdigit(ch))  x = (x << 3) + (x << 1) + ch - ‘0‘, ch = getchar();
    return x * f;
}
void Write(int x) {
    if(x < 0)  putchar(‘-‘), x = -x;
    if(x == 0)  putchar(‘0‘);
    int stk[55], tp = 0;
    while(x) stk[++tp] = x % 10, x /= 10;
    for(int i = tp; i; i--)  putchar(stk[i] + ‘0‘);
}
int Mod, a, b, x, t;
int qpow(int a, int b) {
    int res = 1;
    while(b) {
        if(b & 1)  res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}
map<int, int> mp;
signed main() {
    int T = Read();
    while(T--) {
        mp.clear();
        Mod = Read(), a = Read(), b = Read(), x = Read(), t = Read();
        if(x == t)  {puts("1"); continue;}
        if(a == 0) {
            if(b == t)  puts("2");
            else  puts("-1");
            continue;
        }
        if(a == 1) {
            if(b == 0)  puts("-1");
            else {
                int nyb = qpow(b, Mod - 2), ans = ((t - x) % Mod + Mod) * nyb % Mod;
                printf("%lld\n", ans + 1);
            }
            continue;
        }
        x = ((a - 1) * t % Mod + b) % Mod * qpow((a - 1) * x % Mod + b, Mod - 2) % Mod;
        int res = x, base = sqrt((double)Mod) + 1;
        for(int i = 1; i <= base; i++) {
            mp[res] = i;
            res = res * a % Mod;
        }
        int Res = qpow(a, base), Q = Res, flag = 0;
        for(int i = 1; i <= base; i++) {
            if(mp[Res]) {
                cout << i * base - mp[Res] + 2 << endl;
                flag = 1;
                break;
            }
            Res = Res * Q % Mod;
        }
        if(!flag)  puts("-1");
    }
    return 0;
}

[SDOI2013] 随机数生成器 题解

标签:map   putc   span   putchar   out   bit   pre   ==   get   

原文地址:https://www.cnblogs.com/verjun/p/13881405.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!