zoukankan      html  css  js  c++  java
  • 洛谷P3306 随机数生成器

    题意:给你一个数列,a1 = x,ai = (A * ai-1 + B) % P,求第一个是t的是哪一项,或者永远不会有t。

    解:循环节不会超过P。我们使用BSGS的思想,预处理从t开始跳√P步的,插入Hash表内。

    然后每次把a1跳√P步,来看是否在Hash表中存在。

    这样发现我们有40,WA了60分。为什么呢?考虑是否存在两个数x和y,它们跳一次之后一样了。发现这种情况只会出现在A = 0的时候,于是特判掉A = 0。可获得100分。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010;
      4 
      5 int MO, A, B, op, aim;
      6 
      7 inline int qpow(int a, int b) {
      8     int ans = 1;
      9     while(b) {
     10         if(b & 1) {
     11             ans = 1ll * ans * a % MO;
     12         }
     13         a = 1ll * a * a % MO;
     14         b = b >> 1;
     15     }
     16     return ans;
     17 }
     18 
     19 namespace Hash {
     20     struct Node {
     21         int nex, v, id;
     22     }node[N]; int tp;
     23     const int mod = 999983;
     24     int e[mod];
     25     inline void clear() {
     26         tp = 0;
     27         memset(e, 0, sizeof(e));
     28         return;
     29     }
     30     inline void insert(int v, int id) {
     31         int x = v % mod;
     32         for(int i = e[x]; i; i = node[i].nex) {
     33             if(node[i].v == v) {
     34                 node[i].id = id;
     35                 return;
     36             }
     37         }
     38         node[++tp].nex = e[x];
     39         node[tp].v = v;
     40         node[tp].id = id;
     41         e[x] = tp;
     42         return;
     43     }
     44     inline int find(int v) {
     45         int x = v % mod;
     46         for(int i = e[x]; i; i = node[i].nex) {
     47             if(node[i].v == v) {
     48                 return node[i].id;
     49             }
     50         }
     51         return -1;
     52     }
     53 }
     54 
     55 inline void solve() {
     56     Hash::clear();
     57     scanf("%d%d%d%d%d", &MO, &A, &B, &op, &aim);
     58     if(op == aim) {
     59         printf("%d
    ", 1);
     60         return;
     61     }
     62     if(A == 0) {
     63         if(B == aim) {
     64             printf("2
    ");
     65         }
     66         else {
     67             printf("-1
    ");
     68         }
     69         return;
     70     }
     71     int T = sqrt((double)MO);
     72     for(int i = 0; i < T; i++) {
     73         Hash::insert(aim, i);
     74         //printf("Hash insert %d %d 
    ", aim, i);
     75         aim = (1ll * A * aim % MO + B) % MO;
     76     }
     77     int c = qpow(A, T), d;
     78     if(A == 1) {
     79         d = 1ll * B * T % MO;
     80     }
     81     else {
     82         d = (1ll * (c - 1) * qpow(A - 1, MO - 2) % MO * B % MO + MO) % MO;
     83     }
     84     //printf("c = %d d = %d 
    ", c, d);
     85     for(int i = 1; (i - 1) * T < MO; i++) {
     86         op = (1ll * op * c + d) % MO;
     87         int t = Hash::find(op);
     88         //printf("op = %d  t = %d 
    ", op, t);
     89         if(t != -1) {
     90             printf("%d
    ", i * T - t + 1);
     91             return;
     92         }
     93     }
     94     printf("-1
    ");
     95     return;
     96 }
     97 
     98 int main() {
     99     int T;
    100     scanf("%d", &T);
    101     while(T--) {
    102         solve();
    103     }
    104     return 0;
    105 }
    AC代码
  • 相关阅读:
    Go语言使用grpc
    Go语言中使用protobuf
    proto3语法
    golang标准库io
    走近docker--容器生态系统
    编译技术图式(第四章 语义分析)
    计算机组成原理与结构图示(存储器设计)
    微机原理与汇编接口图式(第一章 数制)
    编译技术图式(第四章 语法分析)03自下而上的语法分析
    计算机组成原理和结构图式(第四章 存储器子系统)
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10824307.html
Copyright © 2011-2022 走看看