zoukankan      html  css  js  c++  java
  • bzoj3122 [SDOI2013]随机数生成器

    bzoj3122 [SDOI2013]随机数生成器

    给定一个递推式, (X_i=(aX_{i-1}+b)mod P)

    求满足 (X_k=t) 的最小整数解,无解输出 (-1)

    (0leq a, b, t, Pleq10^9, P) 为质数

    BSGS


    首先化式子,推得

    [X_k=a^{k-1}x+bdisplaystylesum_{i=0}^{k-2}a_i ]

    因此

    [egin{aligned}displaystylesum_{i=0}^{k-2}a_i&equivfrac{t-a^{k-1}x}{b}pmod P\frac{a^{k-1}-1}{a-1}&equivfrac{t-a^{k-1}x}{b}pmod P\a^{k-1}(b-x+ax)&equiv at-t+bpmod P\a^{k-1}&equivfrac{at-t+b}{b-x+ax}pmod Pend{aligned} ]

    所以上 (BSGS)

    然而这题特判很恶心,不加特判 (0 ext{pts})

    特判如下:

    • (x=t:ans=1)
    • (a=1)
      • (b=0:ans=-1)
      • (b eq0:ans=frac{t-x}{b}+1)
    • (a=0)
      • (b=t:ans=2)
      • (b eq t:ans=-1)

    时间复杂度 (O(Tsqrt P))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int P;
    
    int qp(int a, int k) {
      int res = bool(a);
      for (; k; k >>= 1, a = 1ll * a * a % P) {
        if (k & 1) res = 1ll * res * a % P;
      }
      return res % P;
    }
    
    int bsgs(int a, int b) {
      if (!a && b) return -1;
      map <int, int> s;
      int sz = sqrt(P), inv_a = qp(a, P - 2), pw = qp(a, sz), cur = 1;
      for (int i = 0; i <= sz; i++) {
        s.insert(make_pair(1ll * b * cur % P, i)), cur = 1ll * cur * inv_a % P;
      }
      cur = 1;
      map <int, int> :: iterator it;
      for (int i = 0; i <= sz; i++, cur = 1ll * cur * pw % P) {
        if ((it = s.find(cur)) != s.end()) {
          return i * sz + (it -> second);
        }
      }
      return -1;
    }
    
    int main() {
      int Tests, a, b, x, t, A, B;
      scanf("%d", &Tests);
      while (Tests--) {
        scanf("%d %d %d %d %d", &P, &a, &b, &x, &t);
        a %= P, b %= P, x %= P, t %= P;
        if (x == t) {
          puts("1"); continue;
        } else if (a == 1) {
          if (!b) {
            puts("-1"); continue;
          }
          printf("%d
    ", 1ll * (t - x + P) * qp(b, P - 2) % P + 1);
          continue;
        } else if (!a) {
          puts(b == t ? "2" : "-1");
          continue;
        }
        A = a, B = 1ll * (1ll * a * t - t + b + P) % P * qp((b - x + 1ll * a * x + P) % P, P - 2) % P;
        int ans = bsgs(A, B);
        printf("%d
    ", ~ans ? ans + 1 : ans);
      }
      return 0;
    }
    
  • 相关阅读:
    Inno Setup新建项目
    Modal实现页面跳转和控制器数据传递
    Asp.net Web Api添加异常筛选器
    Inno Setup添加中文安装语言文件
    ubuntu 自动获取IP
    JavaScript 语言基础知识点总结(思维导图)
    自己整理的部分腾讯web前端开发的笔试题目及答案
    spry可折叠面板
    131变化两边,固定中间的布局
    HTML中的dl、dt和dd标记
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/10659176.html
Copyright © 2011-2022 走看看