codevs 1455 路径 计算m^n%p
题目描述 Description
小明从A1到An+1,他知道从A1到A2,从A2到A3,......,从An到An+1都有m条路,且从A1到An+1都只有这些路。小明想知道,从A1地到An+1地共有多少种方法,由于答案可能会很大,小明只要你输出总方案数mod k。
输入描述 Input Description
输入共1行,三个正整数m,n,k
输出描述 Output Description
输出共1行,表示答案
样例输入 Sample Input
3 2 100
样例输出 Sample Output
9
数据范围及提示 Data Size & Hint
假设从A1到A2的所有路为W1,W2,W3,从A2到A3的所有路为W4,W5,W6
方案如下:
W1>>W4
W2>>W4
W3>>W4
W1>>W5
W2>>W5
W3>>W5
W1>>W6
W2>>W6
W3>>W6
共9种方案
对于100%的数据,m,k≤1,000,000,000,n≤101,000,000
题意很明显, 就是m^n%k, 但是n超级大, 所以我们用公式。 m^n%k = m^(n%phi(k)+phi(k))%k。 一下就算出来了好神奇...
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; ll p; ll get_phi(ll n) { ll res = n,i,j; for(i=2;i*i<=n;i++) { if(n%i==0) { n=n/i; while(n%i==0) n=n/i; res=res/i*(i-1); } if(n<(i+1)) break; } if(n>1) res = res/n*(n-1); return res; } ll pow(ll a, ll b) { ll ret = 1; while(b) { if(b&1) ret = ret*a%p; a = a*a%p; b>>=1; } return ret; } int main() { int m; string n; cin>>m>>n>>p; ll phi = get_phi(p); ll tmp = 0; for(int i = 0; i<n.size(); i++) { tmp = tmp*10+n[i]-'0'; tmp %= phi; } tmp += phi; ll ans = pow(1LL*m, tmp)%p; cout<<ans<<endl; return 0; }