0
点赞
收藏
分享

微信扫一扫

POJ 3358 Period of an Infinite Binary Expansion 经典数论:欧拉函数+欧拉定理+快速幂取模


算法分析:

题意:

输入一个有理数p/q(保证是一个小数),然后将其小数部分用二进制表示。求出在此种表示下的循环起点和循环节长度

分析:

十进制小数转化成二进制方法(点这里)

我们可以观察一下1/10这组数据,按照二进制转换法(乘二法),我们可以得到:

1/10  2/10   4/10   8/10   16/10   32/10 ...

然后都分子都尽可能减去10,得到:

1/10  2/10   4/10   8/10   6/10    2/10 ...

出现了重复,那么这个重复就是我们要求的最小循环。

我们来抽象化:给出p/q

1.约分:

p/=gcd(p,q)

q/=gcd(p,q)

2.根据重复出现的条件:p*2^j%q=p*2^i    (i<j,i即为所求点,j-i即为所求循环长度)  

(p*2^j-p*2^i)%q=0

即q | p*2^i(2^(j-i)-1)

根据约分,p,q互质,gcd(p,q)=1;

2^(j-i)-1为奇数,不可能分出2来与q约分

只有2^i里面有2,只有它能约2,

所以q里面有多少2,就是i的结果。

Q=q约2(约到没有为止)

Q | 2^(j-i)-1

(2^(j-i)-1)%Q=0

2^(j-i)≡1(mod Q)

2与Q互质(Q上面的约分2)

欧拉定理:若a与p互质,则a^Φ(p) 1 (modp)

所以说2^(j-i)≡1(mod Q)肯定有解,但不一定是最小解

所以我们从小到大枚举Φ(Q)的因子即可。

 即通过枚举φ(q)的因子(最小因子)就能得出结果.x=φ(q)一定是一个解,但不一定是最小的解,若x=φ(q)不是最小的解,那么最小的解x一定是φ(q)的因子.

证明:假设x是满足2^x≡1(mod n)的最小的x,假设x不是φ(n)的因子,令r=φ(n)mod x,则r>0&&r<x.由2^φ(n)≡ 1(mod n)和2^x≡1(mod n),可以得2^r mod n=1,则存在一个比x还小的数,使得2^r≡1(mod n),这与假设矛盾,所以x为φ(n)因子。

代码实现:

 

Period of an Infinite Binary Expansion

Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3707 Accepted: 1047

Description

Let {x} = 0.a1a2a3... be the binary representation of the fractional part of a rational number z. Suppose that {x} is periodic then, we can write

{x} = 0.a1a2...ar(ar+1ar+2...ar+s)w

for some integers r and s with r ≥ 0 and s > 0. Also, (ar+1ar+2...ar+s)wdenotes a nonterminating and repeating binary subsequence of {x}.

The subsequence x1 = a1a2 ... aris called the preperiod of {x} and x2 = ar+1ar+2 ... ar+s is the period of {x}.

Suppose that |x1| and |x2| are chosen as small as possible then x1 is called the least preperiod and x2 is called the least period of {x}.

For example, x = 1/10 = 0.0001100110011(00110011)w and 0001100110011 is a preperiod and 00110011 is a period of 1/10.

However, we can write 1/10 also as 1/10 = 0.0(0011)w and 0 is the least preperiod and 0011 is the least period of 1/10.

The least period of 1/10 starts at the 2nd bit to the right of the binary point and the the length of the least period is 4.

Write a program that finds the position of the first bit of the least period and the length of the least period where the preperiod is also the minimum of a positive rational number less than 1.

Input

Each line is test case. It represents a rational number p/q where p and q are integers, ≥ 0 and q > 0.

Output

Each line corresponds to a single test case. It represents a pair where the first number is the position of the first bit of the least period and the the second number is the length of the least period of the rational number.

Sample Input

1/10

1/5

101/120

121/1472

Sample Output

Case #1: 2,4

Case #2: 1,4

Case #3: 4,4

Case #4: 7,11

Source

​​Manila 2006​​

#include<cstdio>  
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b == 0 ? a : gcd(b, a % b); }
ll fact[100005];
ll phi(ll n)
{
ll res=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
res=res-res/i;
do{
n/=i;
}while(n%i==0);
}
}
if(n>1) res=res-res/n;
return res;
}

ll quick_qow(ll a,ll b,ll k)
{
long long res=1;
while(b>0)
{
if(b%2) res=(res*a)%k;
a=(a*a)%k;
b/=2;
}
return res;
}

int k;
int factor(ll x) //找x的因子 (包括1和本身)
{
k=0;
for(int i=1;i*i<=x;i++)
{
if(x%i==0)
{
k++;
fact[k]=i;
k++;
fact[k]=x/i;
}
}
}
int main()
{
int t=0;
ll p,q;
while(scanf("%lld/%lld",&p,&q)!=EOF)
{
t++;
ll g=gcd(p,q);
p/=g;
q/=g;
ll cnt=0;
while(q%2==0) //取q里面的2
{
q>>=1;
cnt++;
}
ll ans=phi(q);
factor(ans);
sort(fact+1,fact+k+1);

int i;
for( i=1;i<=k;i++)
{
if(quick_qow(2,fact[i],q)==1)
break;

}
printf("Case #%d: %lld,%lld\n",t,cnt+1,fact[i]);
}
}

 

举报

相关推荐

0 条评论