• poj3358 Period of an Infinite Binary Expansion


    首先要明确分式的二进制表达方式:

    1 //supposing the fraction is a / b, (a < b && (a, b))
    2 //its binary expression is denoted as : 0.bit[1]bit[2]...
    3 seed[0] = a;
    4 for(int i = 1; ; i++){ 5 bit[i] = (seed[i - 1] << 1) / b; 6 seed[i] = (seed[i - 1] << 1) % b;
    7 }

    不妨设其中一个循环节为bit[r]..bit[s],显然有seed[r - 1] = seed[s] 且bit[r] = bit[s + 1],其中循环节长度l = (s - r + 1)。

    由seed[i] = 2i+1 % b, 则有 2r  % b = 2s+1 % b,  即2r(2s-r+1-1) ≡ 0(modb),

    记b = 2t*b1,其中 (b1,2),且令r = t,则 2l≡ 1(modb1)。

    则l|φ(b1),由此枚举b1的约数即可得到周期l。

    并且有初始位置p = t + 1 。

    http://poj.org/problem?id=3358

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cmath>
     5 using namespace std;
     6 typedef __int64 LL;
     7 const int maxn = 1e2 + 10;
     8 int prime[maxn], k;
     9 int fac[maxn];
    10 int a, b, B;
    11 
    12 int power(int a, int p){
    13     a %= B;
    14     int ans = 1;
    15     while(p){
    16         if(p & 1) ans = (LL)ans * a % B;
    17         p >>= 1;
    18         a = (LL)a * a % B;
    19     }
    20     return ans;
    21 }
    22 
    23 int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
    24 
    25 void solve(){
    26     a %= b;
    27     int d = gcd(a, b);
    28     a /= d, b /= d;
    29     int t = 0;
    30     while(b % 2 == 0) b /= 2, ++t;
    31     printf("%d,", ++t);
    32     if(b == 1) { printf("%d
    ",1); return; }
    33     k = 0;
    34     B = b;
    35     int phi = b;
    36     int mid = (int)sqrt(b);
    37     for(int i = 3; i <= mid; i += 2){
    38         if(b % i == 0){
    39             prime[k++] = i;
    40             while(b % i == 0) b /= i;
    41          }
    42     }
    43     if(b != 1) prime[k++] = b;
    44     for(int i = 0; i < k; i++) phi /= prime[i];
    45     for(int i = 0; i < k; i++) phi *= (prime[i] - 1);
    46     k = 0;
    47     for(int i = 1; i * i <= phi; i++){
    48         if(phi % i == 0) fac[k++] = i, fac[k++] = phi / i;
    49     }
    50     sort(fac, fac + k);
    51     for(int i = 0; i < k; i++) if(power(2, fac[i]) == 1){
    52         printf("%d
    ", fac[i]);
    53         break;
    54     }
    55 }
    56 
    57 int main(){
    58     //freopen("in.txt", "r", stdin);
    59     int kase = 0;
    60     while(~scanf("%d/%d", &a, &b)){
    61         printf("Case #%d: ", ++kase);
    62         solve();
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    Linux指令集
    [日记]贝鲁特煎熬第32天
    2019南京区域赛ABCHJK题解 & KMbfs(O(n^3))板子
    欧拉筛质数以及四大积性数论函数(欧拉函数、莫比乌斯函数、约数个数函数、约数和函数)
    简短的自我介绍
    BSTTreap名次树数组&指针实现板子 Ver1.0
    2019银川区域赛BDFGHIKN题解
    安装vs2010
    SPEmailEventReceiver 之导入附件EXCEL
    为incoming mail绑定事件,SPEmailEventReceiver
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4807999.html
Copyright © 2020-2023  润新知