您的位置:首页 > 其它

HDU 2462 The Luckiest number

2016-03-29 23:06 471 查看
题意:给一个数L,是否存在一个数乘上L后的结果只有8,求最小的结果的位数

思路:

自己感觉没有想法就看了下别人的思路,ORZ

令 M=NL

M=(10^X-1)/9*8

M=0 (mod L)

(10^x-1)/9*8=0(mod L)->(10^x-1)=0(mod 9L/Gcd(L,8))

->10^x=1(mod 9L/Gcd(L,8))

这时候就可以用欧拉定理啦

mod=9L/Gcd(L,8)

10^phi(mod)=1 (mod mod)

但是题目求得是最小解,所以枚举phi(mod)的所有因子

这里要注意快速幂的时候由于mod是LL的,所以会爆LL

快速幂内乘法也要用二进制的思想来a*a%mod

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
typedef long long LL;
#define maxn 10005
const int inf=(1<<28)-1;
LL get_phi(LL n)
{
LL res=n,m=n;
for(LL i=2;i*i<=m;++i)
if(m%i==0)
{
res=res/i*(i-1);
while(m%i==0) m/=i;
}
if(m>1) res=res/m*(m-1);
return res;
}
LL Gcd(LL a,LL b)
{
if(!a) return b;
return Gcd(b%a,a);
}
LL modular_multi(LL a, LL b, LL c) {// a * b % c
LL res, temp;
res = 0, temp = a % c;
while (b) {
if (b & 1) {
res += temp;
if (res >= c) {
res -= c;
}
}
temp <<= 1;
if (temp >= c) {
temp -= c;
}
b >>= 1;
}
return res;
}
LL modular_exp(LL a, LL b, LL c) { //a ^ b % c 改成mod_pow就不行,中间发生了溢出,还是这个模板靠谱
LL res, temp;
res = 1 % c, temp = a % c;
while (b) {
if (b & 1) {
res = modular_multi(res, temp, c);
}
temp = modular_multi(temp, temp, c);
b >>= 1;
}
return res;
}
LL factor[2000005];
int main()
{
LL l,Case=0;
while(~scanf("%lld",&l)&&l)
{
printf("Case %lld: ",++Case);
LL m=l/Gcd(l,8)*(LL)9;
if(Gcd(10,m)!=1)
{
printf("0\n");
continue;
}
LL ph=get_phi(m),len=0;
for(LL i=1;i*i<=ph;++i)
if(ph%i==0)
{
factor[++len]=i;
if(i*i!=ph) factor[++len]=ph/i;
}
sort(factor+1,factor+len+1);
int flag=1;
for(LL i=1;i<=len;++i)
if(modular_exp(10,factor[i],m)==1)
{
printf("%lld\n",factor[i]);
flag=0;
break;
}
if(flag)
printf("%lld\n",ph);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数论 HDU