POJ 3696/ HDU 2462 The Luckiest number (数论)
2014-08-21 22:35
453 查看
题目:LINK
给定一个数L, 求使得k*L ==8...8(一串8) 求这一串8的最小长度.
对于8.....8可以写成 (10^x -1)*8/9
即 (10^x - 1)*8/9 = k*n
(10^x - 1)* 8 / gcd(8, n) = 9*n*k/gcd(8,n) ;
令p = 8/gcd(8,n); q = 9*n/gcd(8,n); 这里p,q互质
因此(10^x - 1) 是 q的整数倍
可以得到 10^x = 1 (mod q)
只要求得最小的x(x>0) 满足上面的式子就可以了
这里有两种方法 1),利用欧拉定理: 当gcd(a,b)==1时,a^φ(b)≡1(mod b); 如果gcd(10,q) != 1 无解.否则解为φ(q) 的因子(拉格朗日定理) ,我们可以处理出来φ(q)的所有因子,依次进行判断即可.
2),对于求解 a^x = b (mod c),我们可以采用BSGS算法(我直接套模板) .
1)
2)
给定一个数L, 求使得k*L ==8...8(一串8) 求这一串8的最小长度.
对于8.....8可以写成 (10^x -1)*8/9
即 (10^x - 1)*8/9 = k*n
(10^x - 1)* 8 / gcd(8, n) = 9*n*k/gcd(8,n) ;
令p = 8/gcd(8,n); q = 9*n/gcd(8,n); 这里p,q互质
因此(10^x - 1) 是 q的整数倍
可以得到 10^x = 1 (mod q)
只要求得最小的x(x>0) 满足上面的式子就可以了
这里有两种方法 1),利用欧拉定理: 当gcd(a,b)==1时,a^φ(b)≡1(mod b); 如果gcd(10,q) != 1 无解.否则解为φ(q) 的因子(拉格朗日定理) ,我们可以处理出来φ(q)的所有因子,依次进行判断即可.
2),对于求解 a^x = b (mod c),我们可以采用BSGS算法(我直接套模板) .
1)
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<cmath> #include<map> using namespace std; #define INF 1000000000 typedef __int64 LL; #define N 2000000002 #define M 100005 LL n; vector<LL > save, fac, allfac; LL cou[100]; bool prime[M]; LL gcd(LL a, LL b) { if(!b) return a; return gcd(b, a%b); } LL eular(LL n) { LL ret = 1; for(LL i=2; i*i<=n; i++) { if(n%i ==0) { n /= i; ret *= (i-1); while(n%i == 0) { n /= i; ret *= i; } } } if(n>1) ret *= (n-1) ; return ret; } LL mul(LL x, LL y, LL mod) { LL ret = 0; while(y ) { if(y&1) { ret += x; ret %= mod; } y >>= 1; x += x; x %= mod; } return ret; } LL pow_(LL x, LL y, LL mod) { LL ret = 1; while(y) { if(y&1) { ret = mul(ret, x, mod); } y >>= 1; x = mul(x, x, mod); } return ret ; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif // ONLINE_JUDGE int time = 0; while(scanf("%I64d", &n), n) { LL tmp = n*9/gcd(8, n); printf("Case %d: ", ++time); if(gcd(10, tmp) != 1) { printf("0\n"); continue; } LL pp = eular(tmp); allfac.clear(); for(LL i = 1; i*i <=pp; i++) { if(pp % i == 0) { allfac.push_back(i); allfac.push_back(pp/i); } } sort(allfac.begin(), allfac.end()); for(int i = 0; i < allfac.size(); i++) { LL gg = pow_(10, allfac[i], tmp); if(gg == 1) { printf("%I64d\n", allfac[i]); break; } } } return 0; }
2)
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<cmath> #include<queue> #include<map> #include<set> using namespace std; #define INF 1000000000 typedef __int64 LL; const LL maxn = 65535; struct hash { LL a,b,next; } Hash[maxn << 1]; LL flg[maxn + 66]; LL top,idx; void ins(LL a,LL b) { LL k = b & maxn; if(flg[k] != idx) { flg[k] = idx; Hash[k].next = -1; Hash[k].a = a; Hash[k].b = b; return ; } while(Hash[k].next != -1) { if(Hash[k].b == b) return ; k = Hash[k].next; } Hash[k].next = ++ top; Hash[top].next = -1; Hash[top].a = a; Hash[top].b = b; } LL find(LL b) { LL k = b & maxn; if(flg[k] != idx) return -1; while(k != -1) { if(Hash[k].b == b) return Hash[k].a; k = Hash[k].next; } return -1; } LL gcd(LL a,LL b) { return b?gcd(b,a%b):a; } LL ext_gcd(LL a,LL b,LL& x,LL& y) { LL t,ret; if (!b) { x=1,y=0; return a; } ret=ext_gcd(b,a%b,x,y); t=x,x=y,y=t-a/b*y; return ret; } LL Inval(LL a,LL b,LL n) { LL x,y,e; ext_gcd(a,n,x,y); e=(LL)x*b%n; return e<0?e+n:e; } LL mul(LL x, LL y, LL mod) { LL ret = 0; while(y ) { if(y&1) { ret += x; ret %= mod; } y >>= 1; x += x; x %= mod; } return ret; } LL pow_(LL x, LL y, LL mod) { LL ret = 1; while(y) { if(y&1) { ret = mul(ret, x, mod); } y >>= 1; x = mul(x, x, mod); } return ret ; } LL BabyStep(LL A,LL B,LL C) { top = maxn; ++ idx; LL buf=1%C,D=buf,K; LL i,d=0,tmp; //buf = buf *A%C; for(i=0; i<=100; buf=buf*A%C,++i)if(buf==B)return i; while((tmp=gcd(A,C))!=1) { if(B%tmp)return -1; ++d; C/=tmp; B/=tmp; D=D*A/tmp%C; } LL M=(LL)ceil(sqrt((double)C)); for(buf=1%C,i=0; i<=M; buf=buf*A%C,++i)ins(i,buf); for(i=0,K=pow_((LL)A,M,C); i<=M; D=D*K%C,++i) { tmp=Inval((LL)D,B,C); LL w ; if(tmp>=0&&(w = find(tmp)) != -1) { if(i*M+w+d<=0) continue; //printf("%I64d \n", i*M + w+ d); return i*M+w+d; } } return -1; } LL eular(LL n) { LL ret = 1; for(LL i=2; i*i<=n; i++) { if(n%i ==0) { n /= i; ret *= (i-1); while(n%i == 0) { n /= i; ret *= i; } } } if(n>1) ret *= (n-1) ; return ret; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif // ONLINE_JUDGE LL time = 0; LL n; while(scanf("%I64d", &n), n) { LL tmp = n*9/gcd(8, n); printf("Case %d: ", ++time); //10^X ==1 MOD tmp LL ans = BabyStep(10LL, 1LL, tmp); if(ans<0) { printf("0\n"); continue; } if(ans>0) { printf("%I64d\n", ans); } LL P = tmp, A = 10, D = 1; LL x = eular(P); if(pow_(A, ans + x, P) != D) { printf("0\n"); continue; } LL x1 = x; for(LL i = 2; i * i<= x1; i++) { if(x1 % i ==0) { while(x1 % i == 0) x1 /= i; while(x%i==0 && pow_(A, ans + x/i, P)==D) x/=i; } } if(x1 != 1) { while(x % x1 ==0 && pow_(A, ans + x/x1, P) ==D) x/=x1; } printf("%I64d\n", ans + x); } return 0; }
相关文章推荐
- hdu 2462 poj 3696 The Luckiest number fzu 1017 zoj 1537 Playing with Calculator
- 【原创】【数论】HDU 2462 The Luckiest number
- POJ 3696 The Luckiest number(数论)
- POJ The Luckiest number 3696 数论(处理快速幂过程中超int64的情况)
- POJ 3696 : The Luckiest number - 欧拉函数,快速幂[数论好题]
- POJ 3696 The Luckiest number(08合肥 数论)
- Poj-3696 The Luckiest number(数论)
- poj 3696 The Luckiest number——数论 (快速幂取模,乘法取模模版)
- poj 3696 The Luckiest number (数论-快速幂+欧拉定理)
- POJ 3696 The Luckiest number 推理~~难
- HDU 2462 The Luckiest number
- poj 3696 The Luckiest number(欧拉函数+快速幂取模)
- poj 3696 The Luckiest number(欧拉函数)
- POJ 3696(The Luckiest number-MulMod-原根-乘法取模MulMod)
- POJ 3696 The Luckiest number
- POJ 3696 The Luckiest number 欧拉函数 或 BSGS
- poj3696 The Luckiest number
- POJ 3696 The Luckiest Number 欧拉函数
- HDU 2462 The Luckiest number
- HDU 2462 The Luckiest number