poj3358 Period of an Infinite Binary Expansion

时间:2022-01-14 04:55:35

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?猛戳)。

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

 #include <iostream>
 #include <cstdio>
 typedef long long ll;
 using namespace std;
 ll gcd(ll a,ll b)
 {
     return b?gcd(b,a%b):a;
 }
 ll quick_multiply(ll a,ll b,ll mod)
 {
     ll ans=;
     a%=mod;
     b%=mod;
     while(b)
     {
         ) ans=(ans+a)%mod;
         b>>=;
         a=(a+a)%mod;
     }
     return ans;
 }
 ll quick_power(ll a,ll b,ll mod)
 {
     ll ans=;
     a%=mod;
     while(b)
     {
         ) ans=quick_multiply(ans,a,mod);
         b>>=;
         a=quick_multiply(a,a,mod);
     }
     return ans;
 }
 int main()
 {
     ll a,b;
     ll cnt=;
     while(~scanf("%I64d/%I64d",&a,&b))
     {
         ll k=a,r=b;
         a/=gcd(k,r);
         b/=gcd(k,r);
         ll sum=;
         ==) b/=,sum++;
         printf();
         ll phi=b;
         ll m=b;
         ;i*i<=m;++i)
         {
             )
             {
                 phi=phi/i*(i-);
                 )
                 {
                     m/=i;
                 }
             }
         }
         ) phi=phi/m*(m-);
         ll minn=phi;
         ;i*i<=phi;++i)
         {
             )
             {
                 ,i,b)==) minn=min(minn,i);
                 ,phi/i,b)==) minn=min(minn,phi/i);
             }
         }
         printf("%I64d\n",minn);
     }
 }

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