• SGU 455 Sequence analysis


    http://acm.sgu.ru/problem.php?contest=0&problem=455

      一道关于cycle detection技术的数论题。我用的是wiki中提到的第二种方法,跑出来的时间大约350ms。

      题目说了数的范围是有符号的长整形,开始的时候我考虑到数据可能溢出,于是我就用了模乘法,可是交的时候在第6或第7个test的就TLE了。TLE了以后我就直接删去了模乘法,不过因为开始的时候限制计算的次数的判断的位置放的不对,所以在某些数据上会TLE或者wa。比较幸运的是,我随便测了一组数据就发现问题了。改过来以后就AC了~

    原始代码:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxCnt = 2000000;
    10 
    11 ll A, B, C;
    12 
    13 ll multiMod(ll a, ll b, ll m) {
    14     ll ret = 0;
    15 
    16     while (b) {
    17         if (b & 1) {
    18             ret += a;
    19             ret %= m;
    20         }
    21         a <<= 1;
    22         a %= m;
    23         b >>= 1;
    24     }
    25 
    26     return ret;
    27 }
    28 
    29 ll cal(ll x) {
    30     return (A * x + x % B) % C;
    31 //    if (x >= 0) return (multiMod(A, x, C) + x % B) % C;
    32 //    else if (A >= 0) return (multiMod(x, A, C) + x % B) % C;
    33 //    else return (multiMod(-x, -A, C) + x % B) % C;
    34 }
    35 
    36 ll brent(ll base, int &lam, int &mu) {
    37     ll ep, slow, fast;
    38 
    39     ep = lam = 1;
    40     slow = base;
    41     fast = cal(base);
    42     while (slow != fast) {
    43         if (ep == lam) { // get into a new power of two
    44             slow = fast;
    45             ep <<= 1;
    46             lam = 0;
    47         }
    48         fast = cal(fast);
    49         lam += 1;
    50         if (lam >= maxCnt) return -1;
    51     }
    52 //    cout << slow << " " << fast << endl;
    53     // find the first repetition of lam
    54     mu = 0;
    55     slow = fast = base;
    56     for (int i = 0; i < lam; i++) {
    57         fast = cal(fast);
    58     }
    59 //    cout << "lam " << lam << endl;
    60     while (fast != slow) {
    61         slow = cal(slow);
    62         fast = cal(fast);
    63         mu++;
    64     }
    65 
    66     if (mu + lam <= maxCnt) return mu + lam;
    67     else return -1;
    68 }
    69 
    70 int main() {
    71 //    freopen("in", "r", stdin);
    72 
    73     while (cin >> A >> B >> C) {
    74         int first, cycle;
    75 
    76         cout << brent(1, cycle, first) << endl;
    77 //        cout << first << ' ' << cycle << endl;
    78 //        cout << A << ' ' << B << ' ' << C << endl;
    79 //        for (ll i = 0, k = 1; i <= cycle + first; i++) {
    80 //            cout << k << ' ';
    81 //            k = cal(k);
    82 //        }
    83 //        cout << endl << endl;
    84     }
    85 
    86     return 0;
    87 }

    ——written by Lyon

  • 相关阅读:
    git删除错误分支
    python学习笔记31:操作ini文件
    小说
    PR去字幕补图实操
    数据备份
    文案
    SQL Server 数据文件收缩和查看收缩进度
    ucorelab15堆栈练习
    前端分页使用js css配合后端Pagehelper做分页功能
    Ubuntu网络设置systemdnetworkd管理网络netplan配置文件
  • 原文地址:https://www.cnblogs.com/LyonLys/p/sgu_455_Lyon.html
Copyright © 2020-2023  润新知