HDU2462
题解:
- 找一个最小的l的倍数,满足每一个数都是8,输出数的长度。
- 设8 * (10^n - 1) / 9 = L * p
- 10^n - 1 = p * L * 9 / 8 = p' * L * 9 / gcd(8,9L)
- 10^n
1 (mod 9*L / gcd(8,9L))
- 根据欧拉定理,gcd(10,9L / gcd(8,9L)) == 1才有解。然后在phi(9L / gcd(8,L))的最小满足条件的因子即可。
- 快速幂会超longlong,所以用快速乘法求快速幂
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int const N = 100000 + 10;
ll l,a[N],num;
ll euler(ll n){
ll ans = n;
for(ll i=2;i*i<=n;i++){
if(n % i == 0){
ans = ans / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
void fenjie(ll n){
for(ll i=1;i*i<=n;i++){
if(n % i) continue;
if(i * i == n) a[num++] = i;
else a[num++] = i, a[num++] = n / i;
}
}
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 power(ll a,ll n,ll mod){
ll ans = 1;
while(n){
if(n&1) ans = mul(ans,a,mod);
a = mul(a,a,mod);
n >>= 1;
}
return ans;
}
int main(){
int caser = 0;
while(cin>>l && l){
ll n = 9*l / __gcd(1ll*8,9*l);
if(__gcd(1ll*10,n) != 1) printf("Case %d: %lld\n",++caser,0);
else{
num = 0;
fenjie(euler(n));
sort(a,a+num);
for(ll i=0;i<num;i++)
if(power(1ll*10,a[i],n) == 1){
printf("Case %d: %lld\n",++caser,a[i]);
break;
}
}
}
return 0;
}