POJ 3696 The Luckiest number(08合肥 数论)
来源:互联网 发布:网络刷到单诈骗怎么办 编辑:程序博客网 时间:2024/04/29 09:51
转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove
题目:给出一个数n,找出他的一个倍数,而且这个数每一位都是8,找到最小的那个的位数,否则输出0.
http://poj.org/problem?id=3696
其实是个挺有意思的数论,而且代码难度也不大。
但是可惜就是不会~~~~~~囧
8888888肯定可以写成8*(10^k-1)/9=m*n,n是原数字,k是位数。
稍微整理下8*(10^k-1)=9*n*m,令r=gcd(8,n)
则8/r*(10^k-1)=9*n/r*m。要使8/r*(10^k-1)是9*n/r的倍数,而且8/r与9*n/r互质,所以10^k-1==0(MOD 9*n/r)
即10^k==1 (MOD 9*n/r)。由欧拉定理知道,如果10与9*n/r互质,则10^phi(9*n/r)==1(mod (9*n/r)。
所以无解的情况就是不互质。
然后将phi(9*n/r)分解质因子,得到所有的约数,依次从小判断是否满足等式
注意9*n/r的最大范围为1.8*10^10,小心溢出,我还是用了高精度的模拟乘法
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#define N 80005#define maxn 150005#define LL long long#define pb(a) push_back(a) using namespace std;bool flag[N]={0};int cnt=0,prime[N];LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}void Prime(){for(int i=2;i<N;i++){if(flag[i]) continue;prime[cnt++]=i;for(int j=2;j*i<N;j++)flag[i*j]=true;}}LL get_eular(LL n){LL ret=1;for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++){if(n%prime[i]==0){ret*=prime[i]-1;n/=prime[i];while(n%prime[i]==0){n/=prime[i];ret*=prime[i];}}}if(n>1) ret*=n-1;return ret;}LL fac[N][2],tot;void Split(LL n){tot=0;for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++){if(n%prime[i]==0){fac[tot][0]=prime[i];fac[tot][1]=0;while(n%prime[i]==0){n/=prime[i];fac[tot][1]++;}tot++;}}if(n>1){fac[tot][0]=n;fac[tot++][1]=1;}}vector<LL>fact;void dfs(int idx,LL num){if(idx>=tot){fact.pb(num);return;}LL tmp=1;for(int i=0;i<=fac[idx][1];i++,tmp*=fac[idx][0])dfs(idx+1,num*tmp);}LL MultMod(LL a,LL b,LL MOD){ a%=MOD; b%=MOD; LL ret=0; while(b){ if(b&1){ ret+=a; if(ret>=MOD) ret-=MOD; } a=a<<1; if(a>=MOD) a-=MOD; b=b>>1; } return ret; } LL PowMod(LL a,LL b,LL MOD){LL ret=1;while(b){if(b&1) ret=MultMod(ret,a,MOD);a=MultMod(a,a,MOD);b>>=1;}return ret;}int main(){LL n;int cas=0;Prime();while(scanf("%I64d",&n)!=EOF&&n){LL p=(LL)9*n/gcd(8,n);printf("Case %d: ",++cas);if(gcd(10,p)!=1){printf("0\n");continue;}LL phi=get_eular(p);Split(phi);fact.clear();dfs(0,1);sort(fact.begin(),fact.end());for(int i=0;i<fact.size();i++){if(PowMod(10,fact[i],p)==1){printf("%I64d\n",fact[i]);break;}}}return 0;}
- POJ 3696 The Luckiest number(08合肥 数论)
- Poj-3696 The Luckiest number(数论)
- POJ 3696/ HDU 2462 The Luckiest number (数论)
- POJ The Luckiest number 3696 数论(处理快速幂过程中超int64的情况)
- POJ 3696 The Luckiest number
- POJ 3696 The Luckiest number
- poj 3696 The Luckiest number
- poj 3696 The Luckiest number
- poj-3696 The Luckiest number
- POJ 3696 The Luckiest number
- POJ 3696The Luckiest number
- poj The Luckiest number
- The Luckiest number POJ
- POJ 3696 : The Luckiest number - 欧拉函数,快速幂[数论好题]
- poj 3696 The Luckiest number (数论-快速幂+欧拉定理)
- POJ 3696 The Luckiest number(欧拉函数)
- POJ - 3696 The Luckiest number(求阶)
- POJ 3696 The Luckiest number 推理~~难
- 堆排序
- Unity 3D编程概览
- 类的继承
- wubi-shell-crack
- 查询主键被外键引用的表
- POJ 3696 The Luckiest number(08合肥 数论)
- 我们都一样
- Handle句柄
- DRAM, SRAM, SDRAM的关系与区别
- java 多线程(2)
- 租房合同一定要看仔细
- 二叉树的各种操作 先序 中序 后续 层次 遍历 求树高度 节点深度 知先序中序求后续 二叉排序树
- 数据字典、视图、同义词以及序列
- UNIX IO---再谈文件描述符