您的位置:首页 > 其它

POJ 3696 神TM数论

2016-01-09 10:12 381 查看


题意:链接君已失效

方法:各种数论

解析:老师找了两道数论题。这是第一道,听说比第二道简单多了。然而我并不会,看题解也是好顿理解,这题太值得做了!不做悔一生。

咳,回归正题。这道题就是一个奇妙的数。问你最短须要多少个8组成的数能整除他?所以你有思路么?并没有!有思路你也不会来看我唠叨了!

所以接下来,请你清理下脑子,来看我论证。

首先呢我们能够这么理解

8∗(10x−1)/9=k∗L8*(10^x-1)/9=k*L当中k为常数

然后呢由于这个9在分母上。如果涉及取余或者什么东西的话会非常麻烦。所以我们把它乘到右边,然后会变成什么呢?

8∗(10x−1)=9∗k∗L8*(10^x-1)=9*k*L(我知道以上都是废话)

再进一步8∗(10x−1)/gcd(8,L)=9∗k∗L/gcd(8,L)8*(10^x-1)/gcd(8,L)=9*k*L/gcd(8,L)

接下来便于计算

我们令p=8/gcd(8,L),q=9∗L/gcd(8,L)p=8/gcd(8,L),q=9*L/gcd(8,L)

所以原式变为(10x−1)∗p=k∗q(10^x-1)*p=k*q

由于p与q是互质的,这就是为什么我除了个最大公约数。

所以(10x−1)(10^x-1)%q==0

即10x≡1(modq)10^x≡1(mod q)

又依据欧拉定理

gcd(a,b)==1gcd(a,b)==1可得到aφ(b)≡1(modb)a^{φ(b)}≡1(mod b)

所以10φ(q)≡1(modq)10^{φ(q)}≡1(mod q)

之后呢又有这么个结论,最小的解为φ(q)φ(q)的因子。这个呢是原根的某个定理的推论,简单说明一下原因呢是这种

设k不是φ(n)的约数

10k≡1(modn)10^k≡1 (mod n)

如果gcd(k,φ(n))=s,必定有一个数a,a是k的倍数。a+s是φ(n)的倍数。

10a≡10k≡1(modn)10^a≡10^k≡1 (mod n)

10(a+s)≡10φ(n)≡1(modn)10^{(a+s)}≡10^{φ(n)}≡1 ( mod n)

所以10s≡1(modn)所以10^s≡1 (mod n)

而k不是φ(n)的约数,s是φ(n)的约数,s又是k的约数

所以s<k。而若k是符合要求的,则必定有一个更小的s。

所以答案一定是φ(n)的约数。

之后就乱搞吧!

友情提示!

欧拉可能算爆long long

所以最好把9单独讨论。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100100
using namespace std;
typedef long long ll;
ll prime
;
ll ans[2*N];
int hash
;
int tot;
ll q;
void quick_pri()
{
for(int i=2;i<=100000;i++)
{
if(!hash[i])prime[++tot]=i;
for(int j=1;j<=tot&&prime[j]*i<=100000;j++)
{
hash[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
ll mul(ll a,ll b)
{
ll ret=0;
while(b)
{
if(b&1)ret=(ret+a)%q;
a=(a+a)%q,b>>=1;
}
return ret;
}
ll quick_my(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1)ret=mul(ret,a);
a=mul(a,a),b>>=1;
}
return ret;
}
ll gcd(ll a,ll b)
{
while(b)
{
ll t=b;
b=a%b;
a=t;
}
return a;
}
ll phi(ll a)
{
ll ans=a;
for(int i=1;prime[i]*prime[i]<=a;i++)
{
if(a%prime[i]==0)ans=(ans/prime[i])*(prime[i]-1);
while(a%prime[i]==0)a/=prime[i];
}
if(a!=1)ans=ans*(a-1)/a;
return ans;
}
int main()
{
quick_pri();
ll n;
int casecnt=0;
while(scanf("%lld",&n)&&n!=0)
{
tot=0;
printf("Case %d: ",++casecnt);
q=n/gcd(8,n);
if(gcd(10,9*q)!=1){printf("0\n");continue;}
else
{
ll tmp=phi(q);
if(q%3!=0)tmp*=6;
else tmp*=9;
q*=9;
for(ll i=1;i*i<=tmp;i++)
{
if(tmp%i==0)ans[++tot]=i,ans[++tot]=tmp/i;
}
sort(ans+1,ans+1+tot);
int flag=0;
for(int i=1;i<=tot;i++)
{
if(quick_my(10,ans[i])==1){printf("%lld\n",ans[i]);flag=1;break;}
}
if(!flag)printf("0\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: