标签:++ line ios cas isp cpp std == pac
一道数论欧拉函数和欧拉定理的入门好题。
虽然我提交的时候POJ炸掉了,但是在hdu里面A掉了,应该是一样的吧。
首先我们需要求的这个数一定可以表示成\(\frac{(10^x-1)}{9}\times 8\)。
那么可以列出一个下面的方程
\[\frac{(10^x-1)}{9}\times 8=L\times 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^x\equiv1(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\n", ++ 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\n", ++ cas, ans);
}
}
return 0;
}
「POJ3696」The Luckiest number【数论,欧拉函数】
标签:++ line ios cas isp cpp std == pac
原文地址:https://www.cnblogs.com/chhokmah/p/10695998.html