• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

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

posted @ 2012-10-18 23:38  LyonLys  阅读(252)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3