题目链接:
https://uva.onlinejudge.org/index.phpoption=com_onlinejudge&Itemid=8&page=show_problem&problem=1633
题目大意:给出m(2<= m <= 10000),代表除数;并给出不超过10个数a[i],求解a[0]^a[1]^a[2]^a[3]……. mod m 的值。
解析:由欧拉定理可知 a^b mod m = a^(b mod phi(m) + phi(m)) mod m(phi[m]为m的欧拉函数);
很容易知道,a^b^c mod m = a^(b^c mod phi(m) + phi(m)) mod m = a^(b^(c mod phi(phi(m)) + phi(phi(m))) mod phi(m) + phi(m)) mod m;直接用dfs到最后一个数字,每次传入的m值都是上一层的phi(m),然后边返回,边计算即可。
AC代码如下:
#include <iostream>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <string>
#include <string.h>
#include <sstream>
#include <cctype>
#include <climits>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <vector>
#include <iterator>
#include <algorithm>
#include <stack>
#include <functional>
//cout << "OK" << endl;
#define _clr(x,y) memset(x,y,sizeof(x))
#define _inf(x) memset(x,0x3f,sizeof(x))
#define pb push_back
#define mp make_pair
#define FORD(i,a,b) for (int i=(a); i<=(b); i++)
#define FORP(i,a,b) for (int i=(a); i>=(b); i--)
#define REP(i,n) for (int i=0; i<(n); i++)
using namespace std;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const double EULER = 0.577215664901532860;
const double PI = 3.1415926535897932384626;
const double E = 2.71828182845904523536028;
typedef long long LL;
LL pow_mod(LL a,LL n,LL m)
{
if(n == 0) return 1;
LL x = pow_mod(a,n>>1,m);
LL ans = x*x%m;
if(n&1) ans = ans*a%m;
return ans;
}
int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}
const int N = 1005;
int phi[N * 10], vis[N * 10], m, n, a[N];
void InitOla(){//欧拉的拼写应该是:Euler:)
for (int i = 1; i <= 10000; i++)
phi[i] = i;
for (int i = 2; i <= 10000; i++) {
if (vis[i]) continue;
for (int j = i; j <= 10000; j += i) {
phi[j] = phi[j] / i * (i - 1);
vis[j] = 1;
}
}
}
int solve(int i, int mod){
if(i == n-1)
return (a[i] >= mod) ? (a[i] % mod + mod) : a[i];
int tem = solve(i+1, phi[mod]); //每次进入下一层的m都是在这一层基础上的phi(m)
return pow_mod(a[i], tem, mod) + mod;//直接套用欧拉定理,这里用快速幂确保速度
}
int main(){
InitOla();//得到小于m的所有phi(m)的值,便于在dfs中使用
int cas = 0;
while(cin >> m, m){
cin >> n;
for(int i = 0; i < n; i ++){
cin >> a[i];
}
cout << "Case #" << ++cas << ": " << solve(0, m) % m << endl;
}
return 0;
}