Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2378 | Accepted: 501 |
Description
Given integers b, n, and i, we define the function f(x) recursively by f(x) = bf(x-1) if x > 0, and f(0)=1. Your job is to efficiently compute the last n decimal digits of f(i).
Input
Output
Sample Input
2 4 7 10 10 6 3 10 7 0
Sample Output
0065536 000000 4195387
Source
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 300000; ll b,n,p,tot,num[10],cnt,ans,f[110][110]; int prime[1000010],phi[10000010]; bool vis[10000010]; ll qpow(ll a,ll b,ll mod) { ll res = 1; while(b) { if (b & 1) res = (res * a) % mod; b >>= 1; a = (a * a) % mod; } return res; } void init() { phi[1] = 1; phi[10000000] = 4000000; phi[4000000] = 1600000; phi[1600000] = 640000; phi[640000] = 256000; for (int i = 2; i <= maxn; i++) { if (!vis[i]) { prime[++tot] = i; phi[i] = i - 1; } for (int j = 1; j <= tot; j++) { ll t = prime[j] * i; if (t > maxn) break; vis[t] = 1; if (i % prime[j] == 0) { phi[t] = phi[i] * prime[j]; break; } phi[t] = phi[i] * (prime[j] - 1); } } } ll solve(ll dep,ll mod) { if (dep == 1) return b; if (mod == 1) return 0; if (f[b][dep] == -1) { ll temp = phi[mod]; ll tt,temp2 = solve(dep - 1,temp); tt = qpow(b,temp2 + temp,mod); return f[b][dep] = tt; } return f[b][dep] % mod; } int main() { memset(f,-1,sizeof(f)); init(); while (~scanf("%lld",&b) && b) { cnt = 0; memset(num,0,sizeof(num)); scanf("%lld%lld",&n,&p); if (p == 0) printf("0\n"); else { ll cur = p; p = qpow(10,p,100000010); if (f[b][n] != -1) ans = f[b][n]; else { if (n == 2 && b <= 6) ans = qpow(b,b,10000000); else if (n == 3 && b <= 3) ans = qpow(b,qpow(b,b,10000000),10000000); else if (n == 4 && b == 2) ans = qpow(b,qpow(b,qpow(b,b,10000000),10000000),10000000); else ans = solve(n,10000000); f[b][n] = ans; } while (ans) { num[++cnt] = ans % 10; ans /= 10; } for (int i = cur; i >= 1; i--) printf("%d",num[i]); printf("\n"); } } return 0; }