UVa 10692 - Huge Mod (数论 + 欧拉定理扩展)

来源:互联网 发布:php类的反射 编辑:程序博客网 时间:2024/05/08 11:39

题意

计算abcdmodm

思路

用欧拉公式即可,不过要保证符合b>=ϕ(m) 的前提!网上很多代码都是错的。可以试下这组数据:1000 3 12 1 1。
就连uHunt上的标程都是错的。。

写了个Check函数每次判断是不是符合条件。

代码

#include <stack>#include <cstdio>#include <list>#include <cassert>#include <set>#include <fstream>#include <iostream>#include <string>#include <sstream>#include <vector>#include <queue>#include <functional>#include <cstring>#include <algorithm>#include <cctype>#pragma comment(linker, "/STACK:102400000,102400000")#include <string>#include <map>#include <cmath>//#include <ext/pb_ds/assoc_container.hpp>//#include <ext/pb_ds/hash_policy.hpp>//using namespace std;//using namespace __gnu_pbds;#define LL long long#define ULL unsigned long long#define SZ(x) (int)x.size()#define Lowbit(x) ((x) & (-x))#define MP(a, b) make_pair(a, b)#define MS(p, num) memset(p, num, sizeof(p))#define PB push_back#define X first#define Y second#define ROP freopen("input.txt", "r", stdin);#define MID(a, b) (a + ((b - a) >> 1))#define LC rt << 1, l, mid#define RC rt << 1|1, mid + 1, r#define LRT rt << 1#define RRT rt << 1|1#define FOR(i, a, b) for (int i=(a); (i) < (b); (i)++)#define FOOR(i, a, b) for (int i = (a); (i)<=(b); (i)++)#define TRAVERSAL(u, i) for (int i = head[u]; i != -1; i = edge[i].nxt)const double PI = acos(-1.0);const int INF = 0x3f3f3f3f;const double eps = 1e-8;const int MAXN = 10000+10;const int MOD = 100000007;const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };const int seed = 131;int cases = 0;typedef std::pair<int, int> pii;int phi[MAXN], m, n;char str[1000];int num[20];int pow_mod(LL a, LL n, LL m){    int ret = 1;    while (n)    {        if (n & 1) ret = ret * a % m;        a = a * a % m;        n >>= 1;    }    return ret;}void get_phi_table(){    for (int i = 2; i < MAXN; i++) if (!phi[i])        for (int j = i; j < MAXN; j += i)        {            if (!phi[j]) phi[j] = j;            phi[j] = phi[j] / i * (i-1);        }}int Check(int u, int target){    if (u == n-1) return num[u];    int ret = Check(u+1, target);    if (ret >= target) return target;    int tmp = 1;    for (int i = 0; i < ret; i++)    {        tmp = tmp * num[u];        if (tmp >= target) return target;    }    return tmp;}int simple_pow(int u){    if (u == n-1) return num[u];    return pow_mod(num[u], simple_pow(u+1), INF);}int dfs(int u, int mod){    if (mod == 1) return 0;    if (u == n-1) return num[u] % mod;    int ans = dfs(u+1, phi[mod]);    if (Check(u+1, phi[mod]) >= phi[mod]) return pow_mod(num[u], ans + phi[mod], mod);    else return pow_mod(num[u], simple_pow(u+1), mod);}int main(){    //ROP;    get_phi_table();    while (gets(str), str[0] != '#')    {        char *p = strtok(str, " ");        sscanf(p, "%d", &m);        p = strtok(NULL, " ");        sscanf(p, "%d", &n);        for (int i = 0; i < n; i++)        {            p = strtok(NULL, " ");            sscanf(p, "%d", &num[i]);        }        printf("Case #%d: %d\n", ++cases, dfs(0, m));    }    return 0;}
0 0
原创粉丝点击