【POJ3696】The Luckiest Number-欧拉定理+快速幂
2017-05-26 23:57
295 查看
测试地址:The Luckiest Number
题目大意:给出一个正整数L(≤2,000,000,000),要使正整数888...8K位能整除L,求最小的K,如果不存在这样的K则输出0。
做法:这题的思路很神……没看题解的时候根本不知道怎么做,调也调了好一会,我好弱啊……
这一题需要使用欧拉定理+快速幂来解决。
我们发现999...9K位可以表示为10K−1,所以888...8K位可以表示为8/9×(10K−1),那么存在一个整数p使得8/9×(10K−1)=L×p,所以10K−1=9/8×L×p。由于等式右边要是整数,那么p应该满足8|(L×p)。因为L已经包含gcd(L,8)这些因子,所以p需要包含8/gcd(L,8)这些因子,所以可以将p写成p=8/gcd(L,8)×p1。将其代入前面的式子,可以得到10K−1=9×L/gcd(L,8)×p1,设m=9×L/gcd(L,8),则原式可以写成10K−1=m×p1,这样我们就把问题转化成了求同余方程10K≡1(modm)的最小的正整数解。根据欧拉定理,可以得到10φ(m)≡1(modm),可以证明如果K是一个小于φ(m)的解,那么K|φ(m)。那么我们就可以按照下列步骤完成这一题:
1.求出m,φ(m)和φ(m)的所有质因子。这一步可以用O(N−−√)的试除法来做。
2.令x=φ(m),对于φ(m)的每一个质因子pi,判断10x/pi%m是否等于1,如果等于则令x=x/pi,否则跳过。由于指数很大,需要使用快速幂来算出结果,而因为数字直接乘起来可能会溢出,要用快速乘代替乘法。
3.对所有质因子进行以上操作后,最后的x就是最小的K。
那么无解的情况呢?显然可知,如果gcd(10,m)≠1,那么上面的同余方程就无解。这样我们就完美解决了这一题。
犯二的地方:试除法忘记探测最后剩余是不是1了,导致可能漏掉一个质因子,以后要注意……
以下是本人代码:
题目大意:给出一个正整数L(≤2,000,000,000),要使正整数888...8K位能整除L,求最小的K,如果不存在这样的K则输出0。
做法:这题的思路很神……没看题解的时候根本不知道怎么做,调也调了好一会,我好弱啊……
这一题需要使用欧拉定理+快速幂来解决。
我们发现999...9K位可以表示为10K−1,所以888...8K位可以表示为8/9×(10K−1),那么存在一个整数p使得8/9×(10K−1)=L×p,所以10K−1=9/8×L×p。由于等式右边要是整数,那么p应该满足8|(L×p)。因为L已经包含gcd(L,8)这些因子,所以p需要包含8/gcd(L,8)这些因子,所以可以将p写成p=8/gcd(L,8)×p1。将其代入前面的式子,可以得到10K−1=9×L/gcd(L,8)×p1,设m=9×L/gcd(L,8),则原式可以写成10K−1=m×p1,这样我们就把问题转化成了求同余方程10K≡1(modm)的最小的正整数解。根据欧拉定理,可以得到10φ(m)≡1(modm),可以证明如果K是一个小于φ(m)的解,那么K|φ(m)。那么我们就可以按照下列步骤完成这一题:
1.求出m,φ(m)和φ(m)的所有质因子。这一步可以用O(N−−√)的试除法来做。
2.令x=φ(m),对于φ(m)的每一个质因子pi,判断10x/pi%m是否等于1,如果等于则令x=x/pi,否则跳过。由于指数很大,需要使用快速幂来算出结果,而因为数字直接乘起来可能会溢出,要用快速乘代替乘法。
3.对所有质因子进行以上操作后,最后的x就是最小的K。
那么无解的情况呢?显然可知,如果gcd(10,m)≠1,那么上面的同余方程就无解。这样我们就完美解决了这一题。
犯二的地方:试除法忘记探测最后剩余是不是1了,导致可能漏掉一个质因子,以后要注意……
以下是本人代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define ll long long using namespace std; ll L,fac[1010]={0}; ll gcd(ll a,ll b) { return (b==0)?a:gcd(b,a%b); } ll phi(ll x) { ll p=x,s=x; for(ll i=2;i*i<=s;i++) if (!(x%i)) { p=p/i*(i-1); while(!(x%i)) x/=i; } if (x>1) p=p/x*(x-1); return p; } void find_factor(ll x) { ll s=x; fac[0]=0; for(ll i=2;i*i<=s;i++) if (!(x%i)) { fac[++fac[0]]=i; while(!(x%i)) x/=i; } if (x>1) fac[++fac[0]]=x; } ll mult(ll a,ll b,ll mod) { a%=mod,b%=mod; ll s=a,sum=0; while(b) { if (b&1) { sum+=s; if (sum>=mod) sum-=mod; } b>>=1; s<<=1; if (s>=mod) s-=mod; } return sum; } ll power(ll a,ll b,ll mod) { ll s=a,sum=1; while(b) { if (b&1) sum=mult(sum,s,mod); b>>=1;s=mult(s,s,mod); } return sum; } int main() { int t=0; while(scanf("%lld",&L)&&L) { t++; ll m=L/gcd(L,8)*9,p=phi(m),x=p; if (gcd(m,10)!=1) {printf("Case %d: 0\n",t);continue;} find_factor(p); for(int i=1;i<=fac[0];i++) { while(1) { x/=fac[i]; if (power(10,x,m)!=1) { x*=fac[i]; break; } else if (x%fac[i]) break; } } printf("Case %d: %lld\n",t,x); } return 0; }
相关文章推荐
- POJ3696:The Luckiest number (欧拉定理)
- poj 3696 The Luckiest number (数论-快速幂+欧拉定理)
- [POJ3696]The Luckiest number(数论)
- poj 3696 The Luckiest number——数论 (快速幂取模,乘法取模模版)
- POJ3696 The Luckiest number【欧拉函数】
- poj 3696 The Luckiest number(欧拉函数+快速幂取模)
- POJ3696:The Luckiest number(欧拉函数||求某数最小的满足题意的因子)
- 【hdu2462】【数论】【欧拉函数+欧拉定理+大数快速幂】The Luckiest number
- POJ 3696 : The Luckiest number - 欧拉函数,快速幂[数论好题]
- poj3696 The Luckiest number By Assassin
- poj 3696 The Luckiest number(欧拉函数)
- The Luckiest number(hdu2462)
- POJ 3696 The Luckiest number 欧拉函数 或 BSGS
- POJ3696 The Luckiest number
- poj 3696 The Luckiest number 欧拉函数在解a^x=1modm的应用
- hdu 2462 The Luckiest number
- poj3696 The Luckiest number
- poj 3696 The Luckiest number
- poj 3696 The Luckiest number
- Poj-3696 The Luckiest number(数论)