Acwing202. 最幸运的数字
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Acwing202. 最幸运的数字相关的知识,希望对你有一定的参考价值。
题意:
现在给定一个正整数 L,请问至少多少个 8 连在一起组成的正整数(即最小幸运数字)是 L 的倍数。
题解:
x个8连在一起组成的正整数可写作
8
(
1
0
x
−
1
)
/
9
8(10^x-1)/9
8(10x−1)/9。现在要求一个最小的x,满足
L
∣
8
(
1
0
x
−
1
)
9
L|\\frac{8(10^x-1)}{9}
L∣98(10x−1).
L
∣
8
(
1
0
x
−
1
)
9
L|\\frac{8(10^x-1)}{9}
L∣98(10x−1)=
9
L
∣
8
(
1
0
x
−
1
)
9L|8(10^x-1)
9L∣8(10x−1)
我们设d=gcd(L,8)
有:gcd(L/d,8/d)=1
说明8/d与L/d互质
8(10^x-1)是9L的质数,有
9
L
d
∣
8
d
(
1
0
x
−
1
)
\\frac{9L}{d}|\\frac{8}{d}(10^x-1)
d9L∣d8(10x−1)
因为8/d与L/d互质,所以
9
L
d
∣
(
1
0
x
−
1
)
\\frac{9L}{d}|(10^x-1)
d9L∣(10x−1)
再推导有:
1
0
x
≡
1
(
m
o
d
9
L
d
)
10^x \\equiv1 (\\bmod \\frac{9L}{d})
10x≡1(modd9L)
引理:
若正整数a,n互质,则满足
a
x
≡
1
(
m
o
d
n
)
a^x\\equiv 1(\\bmod n)
ax≡1(modn)的最小正整数x0是
ϕ
(
n
)
的
约
数
\\phi(n)的约数
ϕ(n)的约数
所以我们只需要求出欧拉函数
ϕ
(
9
L
d
)
\\phi(\\frac{9L}{d})
ϕ(d9L),枚举它的所有约数,用快速幂判断是否符合条件即可。时间复杂度是
O
(
L
log
L
)
O(\\sqrt{L}\\log{L})
O(LlogL)
时间没问题,但是注意,你的longlong会被下面数据爆掉,所以要用到一个小技巧,叫龟速乘
1999999999
1213131311
1242342334
0
龟速乘其实就是把快速幂中乘法部分展开,将乘法转成加法做,每次运算都取mod,这样就不会爆
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
x= 0;
char c= getchar();
bool flag= 0;
while (c < '0' || c > '9')
flag|= (c == '-'), c= getchar();
while (c >= '0' && c <= '9')
x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
if (flag)
x= -x;
read(Ar...);
}
template <typename T> inline void write(T x)
{
if (x < 0) {
x= ~(x - 1);
putchar('-');
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef LOCAL
startTime= clock();
freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{
#ifdef LOCAL
endTime= clock();
printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
ll mul(ll a, ll b, ll mod)
{
ll ans= 0;
while (b) {
if (b & 1)
ans= (ans + a) % mod;
a= (a + a) % mod;
b>>= 1;
}
return ans;
}
ll poww(ll a, ll b, ll mod)
{
ll ans= 1;
while (b) {
if (b & 1)
ans= mul(ans, a, mod) % mod;
a= mul(a, a, mod) % mod;
b>>= 1;
}
return ans % mod;
}
ll phi(ll n)
{
ll ans= n;
for (int i= 2; i <= sqrt(n); i++) {
if (n % i == 0) {
ans= ans / i * 1ll * (i - 1);
while (n % i == 0)
n/= i;
}
}
if (n > 1)
ans= ans / n * 1ll * (n - 1);
return ans;
}
int main()
{
//rd_test();
ll l;
int cas= 0;
while (cin >> l) {
if (l == 0)
break;
ll mod= l / __gcd(8ll, l) * 9ll;
ll p= phi(mod);
ll ret= 1e18;
for (ll x= 1; x <= sqrt(p); x++) {
if (p % x != 0)
continue;
if (poww(10, x, mod) == 1)
ret= min(ret, x);
if (poww(10, p / x, mod) == 1)
ret= min(ret, p / x);
}
printf("Case %d: ", ++cas);
printf("%lld\\n", ret == 1e18 ? 0 : ret);
}
return 0;
//Time_test();
}
以上是关于Acwing202. 最幸运的数字的主要内容,如果未能解决你的问题,请参考以下文章
动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条
动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条