您的位置:首页 > 其它

poj 3358 Period of an Infinite Binary Expansion(欧拉函数+欧拉定理)

2013-12-05 22:45 573 查看
[align=center]PeriodofanInfiniteBinaryExpansion[/align]

TimeLimit:1000MSMemoryLimit:65536K
TotalSubmissions:2769Accepted:718
Description

Let{x}=0.a1a2a3...bethebinaryrepresentationofthefractionalpartof
arationalnumberz.Supposethat{x}isperiodicthen,wecanwrite

{x}=0.a1a2...ar(ar+1ar+2...ar+s)w
forsomeintegersrandswithr≥0ands>0.Also,(ar+1ar+2...ar+s)wdenotes
anonterminatingandrepeatingbinarysubsequenceof{x}.

Thesubsequencex1=
a1a2...
ariscalledthepreperiodof{x}and
x2=ar+1ar+2...
ar+sisthe
periodof{x}.

Supposethat|x1|and|x2|arechosenassmallaspossiblethen
x1iscalledtheleastpreperiodand
x2iscalledtheleastperiodof{x}.

Forexample,x=1/10=0.0001100110011(00110011)wand0001100110011isapreperiodand00110011isaperiodof1/10.

However,wecanwrite1/10alsoas1/10=0.0(0011)wand0istheleastpreperiodand0011istheleastperiodof1/10.

Theleastperiodof1/10startsatthe2ndbittotherightofthebinarypointandthethelengthoftheleastperiodis4.

Writeaprogramthatfindsthepositionofthefirstbitoftheleastperiodandthelengthoftheleastperiodwherethepreperiodisalsotheminimumofapositiverationalnumberlessthan1.

Input

Eachlineistestcase.Itrepresentsarationalnumberp/qwhere
pandqareintegers,p≥0andq>0.

Output

Eachlinecorrespondstoasingletestcase.Itrepresentsapairwherethefirstnumberisthepositionofthefirstbitoftheleastperiodandthethesecondnumberisthelengthoftheleastperiodoftherationalnumber.

SampleInput
1/10
1/5
101/120
121/1472

SampleOutput
Case#1:2,4
Case#2:1,4
Case#3:4,4
Case#4:7,11



题意:给出小数p/q的十进制表示,求当p/q的结果化为二进制的小数时,使p/q的循环节和非循环节都最短时,循环节开始的位置和循环节的长度。

思路:以下的discuss的做法:

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

1/102/104/108/1016/1032/10...

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

1/102/104/108/106/102/10...

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

抽象出模型如下:对p/q首先p'=p/gcd(p,q)q'=q/gcd(p,q)(即化为最简);

然后我们就是求p'*2^i==p'*2^j(modq')(“==”表示同余,i<j)

经过变换得到:p'*2^i*(2^(j-i)-1)==0(modq')也就是q'|p'*2^i*(2^(j-i)-1)

由于gcd(p',q')=1,得到:q'|2^i*(2^(j-i)-1)

因为2^(j-i)-1为奇数,所以q'有多少个2的幂,i就是多少,而且i就是循环开始位置的前一位。

那么令q''为q'除去2的幂之后的数此时q''|2^(j-i)-1也就是求出x,使得2^x==1(modq'')

而根据欧拉定理,

φ(n)为n的欧拉函数,那么我们要求出的x即为φ(n)的满足2^x%q''=1的最小因子。


AC代码:

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<queue>
#include<ctime>
#include<algorithm>

#definell__int64

usingnamespacestd;

intfac[100005];
intcnt;
intgcd(inta,intb)
{
returnb==0?a:gcd(b,a%b);
}
inteuler(intn)
{
intret=n;
for(inti=2;i*i<=n;i++)
if(n%i==0)
{
ret=ret/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1)ret=ret/n*(n-1);
returnret;
}
voidget_factor(intn)
{
cnt=0;
for(inti=1;i*i<=n;i++)
if(n%i==0)
{
fac[cnt++]=i;
fac[cnt++]=n/i;
}
}
intMontgomery(inta,intb,intm)
{
intr=1;
a%=m;
while(b)
{
if(b&1)r=(longlong)r*a%m;
a=(longlong)a*a%m;
b>>=1;
}
returnr;
}
intmain()
{
intp,q,c=0;
intans1,ans2;
while(~scanf("%d/%d",&p,&q))
{
intGCD=gcd(p,q);
p/=GCD;
q/=GCD;
ans1=0;
while(q%2==0)
{
ans1++;
q/=2;
}
intphi=euler(q);
get_factor(phi);
sort(fac,fac+cnt);

for(inti=0;i<cnt;i++)
if(Montgomery(2,fac[i],q)==1)
{
ans2=fac[i];
break;
}
printf("Case#%d:%d,%d\n",++c,ans1+1,ans2);
}
return0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: