码迷,mamicode.com
首页 > 其他好文 > 详细

poj3358 Period of an Infinite Binary Expansion

时间:2018-01-03 19:46:38      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:col   ret   神题   mod   ref   整数   长度   while   blank   

Period of an Infinite Binary Expansion

    题目大意:给你一个分数,求这个分数二进制表示下从第几位开始循环,并求出最小循环节长度。

    注释:int范围内。

      想法:这题说实话,是一道神题!我们思考一下,如何将一个小数换成二进制?连续的乘2,然后取首位。这样的比较简洁的转换方式注定了这题其实是可做的。我们可以抓住循环节的在这样的方法下是怎样形成的?显然,存在一个x,使得每多乘$2^x$都会使得所形成的答案相同。第二点,我们知道,一个分数的循环节开始之前是不参与循环的。这样,我们思考,多次反复的乘以2,它的整数部分modb是相同的对吧!?!我们在此就有一个式子,就是说

    $2^i\cdot a\equiv 2^j\cdot a(mod\ b)$。其中j>i

    可以变形为$2^j\cdot a-2^i\cdot a\equiv 0(mod\ b)$

    $\Rightarrow 2^i\cdot a\cdot(2^{j-i}-1)$首先,我们在此之前不妨现将a,b弄成互质。现在,gcd(a,b)=1,所以,我们有

    $2^i\cdot (2^{j-i}-1)\equiv 0(mod\ b)$

    显然,我们想求最小值,我们发现,如果i的值增加,循环节的长度是不会改变的,所以,我们必须求出最小的且满足题意的i,而这个i,就是b中2的个数。剩下的,就是另一道题了。参考博主博客The Luckiest Number(The Luckiest Number?猛戳)。

    最后,附上丑陋的代码......

 1 #include <iostream>
 2 #include <cstdio>
 3 typedef long long ll;
 4 using namespace std;
 5 ll gcd(ll a,ll b)
 6 {
 7     return b?gcd(b,a%b):a;
 8 }
 9 ll quick_multiply(ll a,ll b,ll mod)
10 {
11     ll ans=0;
12     a%=mod;
13     b%=mod;
14     while(b)
15     {
16         if(b&1) ans=(ans+a)%mod;
17         b>>=1;
18         a=(a+a)%mod;
19     }
20     return ans;
21 }
22 ll quick_power(ll a,ll b,ll mod)
23 {
24     ll ans=1;
25     a%=mod;
26     while(b)
27     {
28         if(b&1) ans=quick_multiply(ans,a,mod);
29         b>>=1;
30         a=quick_multiply(a,a,mod);
31     }
32     return ans;
33 }
34 int main()
35 {
36     ll a,b;
37     ll cnt=0;
38     while(~scanf("%I64d/%I64d",&a,&b))
39     {
40         ll k=a,r=b;
41         a/=gcd(k,r);
42         b/=gcd(k,r);
43         ll sum=0;
44         while(b%2==0) b/=2,sum++;
45         printf("Case #%I64d: %I64d,",++cnt,sum+1);
46         ll phi=b;
47         ll m=b;
48         for(int i=2;i*i<=m;++i)
49         {
50             if(m%i==0)
51             {
52                 phi=phi/i*(i-1);
53                 while(m%i==0)
54                 {
55                     m/=i;
56                 }
57             }
58         }
59         if(m!=1) phi=phi/m*(m-1);
60         ll minn=phi;
61         for(ll i=1;i*i<=phi;++i)
62         {
63             if(phi%i==0)
64             {
65                 if(quick_power(2,i,b)==1) minn=min(minn,i);
66                 if(quick_power(2,phi/i,b)==1) minn=min(minn,phi/i);
67             }
68         }
69         printf("%I64d\n",minn);
70     }
71 }

    小结,我们发现,这题对于a的取值并没有什么要求,证明是显然的。

poj3358 Period of an Infinite Binary Expansion

标签:col   ret   神题   mod   ref   整数   长度   while   blank   

原文地址:https://www.cnblogs.com/ShuraK/p/8185126.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!