UVa 10692 Huge Mods(快速幂)(欧拉定理)

题目链接:
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值