zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/LyonLys/p/sgu_455_Lyon.html
Copyright © 2011-2022 走看看