「POJ3696」The Luckiest number数论,欧拉函数
Posted chhokmah
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「POJ3696」The Luckiest number数论,欧拉函数相关的知识,希望对你有一定的参考价值。
# 题解
一道数论欧拉函数和欧拉定理的入门好题。
虽然我提交的时候POJ炸掉了,但是在hdu里面A掉了,应该是一样的吧。
首先我们需要求的这个数一定可以表示成(frac{(10^x-1)}{9} imes 8)。
那么可以列出一个下面的方程
[frac{(10^x-1)}{9} imes 8=L imes k]
设(d=gcd(9L,8)=gcd(L,8))
[frac89(10^x-1)=Lk]
[frac{8(10^x-1)}d=frac{9Lk}{d}]
令(p=frac8d,q=frac{9L}d),易证(p)和(q)互质。
[p(10^x-1)=qk]
可得(q|10^x-1),所以得到了(10^xequiv1(mod q))
根据欧拉定理,当(10)和(q)互质,必定有一组解,是(varphi(q))
那么最小的一组解一定是(varphi(q))的一个约数。
那么欧拉函数计算一下,然后枚举一下约数,快速幂判断一下就好了。
代码
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#define ll long long
#define db double
using namespace std;
ll L, ans;
bool fg;
ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y) ; }
ll mulmod(ll x, ll y, ll mod) {
ll res = 0ll;
for (; y; y >>= 1) { if (y & 1) res = (res + x) % mod; x = (x << 1) % mod; }
return res;
}
ll power(ll x, ll y, ll mod) {
ll res = 1ll;
for (; y; y >>= 1) { if (y & 1) res = mulmod(res, x, mod); x = mulmod(x, x, mod); }
return res;
}
ll euler(ll x) {
ll res = x;
for (ll i = 2; i * i <= x; i ++) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
return res;
}
int main() {
int cas = 0;
while (~scanf("%I64d", &L) && L) {
ll d = gcd(L, 8), q = 9 * L / d; fg = 0;
if (gcd(q, 10) != 1) printf("Case %d: 0
", ++ cas);
else {
ll phi = euler(q), m = sqrt((db)(phi));
ans = phi;
for (int i = 1; i <= m; i ++)
if (phi % i == 0 && power(10, i, q) == 1) { ans = i; fg = 1; break; }
if (!fg) for (int i = m; i >= 2; i --) {
if (phi % i == 0 && power(10, phi / i, q) == 1) { ans = phi / i; break; }
}
printf("Case %d: %I64d
", ++ cas, ans);
}
}
return 0;
}
以上是关于「POJ3696」The Luckiest number数论,欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章