uva 10692 Huge Mods 超大数取模

  vjudge上题目链接:Huge Mods

  附上截图:

  题意不难理解,因为指数的范围太大,所以我就想是不是需要用求幂大法: AB % C = AB % phi(C) + phi(C) % C ( B > phi(C) ) 呢?后来发现确实需要用到,而且因为它有很多重指数,所以需要 dfs,深搜到最后一层后才返回,每次向上一层返回用求幂公式处理好的指数,然后本层用同样的原理去处理好当前层取模的值,并向上一层返回。欧拉函数预处理即可,这题的结束也有点卡人,我是用输入挂来处理的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int M = 10006;
 6
 7 int phi[M] = {0,1,};
 8 inline void init(int n = M - 3) {
 9     for(int i = 2; i <= n; ++i)
10         if(!phi[i])
11         for(int j = i; j <= n; j += i) {
12             if(!phi[j])   phi[j] = j;
13             phi[j] = phi[j] / i *(i - 1);
14         }
15 }
16
17 #include<cctype>
18 inline int read(int &x) {
19     x = 0;
20     char ch = getchar();
21     while(!isdigit(ch) && ch != ‘#‘)    ch = getchar();
22     if(ch == ‘#‘)   return 0;
23     while(isdigit(ch)) {
24         x = x * 10 + (ch - ‘0‘);
25         ch = getchar();
26     }
27     return 1;
28 }
29
30 int quick_mod(int a, int b, int m) {
31     int res = 1;
32     while(b) {
33         if(b & 1)   res = res * a % m;
34         a = a * a % m;
35         b >>= 1;
36     }
37     return res;
38 }
39
40 int m,n,a[16];
41
42 // id 为当前层的数组下标,mod 为当前层进行取模的模数,
43 // 由求幂公式可知 mod 每次向下一层传参时是传当前层的 mod 的欧拉函数,也就是 phi[mod] 的值
44 // dfs 向上一层返回用求幂公式处理好的指数,更多的参看代码了
45 int dfs(int id, int mod) {
46     if(id == n) {
47         if(a[id] > mod)   return a[id] % mod + mod;
48         else    return a[id];
49     }
50     int pow = dfs(id + 1, phi[mod]);
51
52     int mul = 1, c = a[id], num = pow;
53
54     // 因为忽略了 c <= mod 这个判断导致中间数据溢出,害我 TLE 了数次,T 得不明真相,
55     // 还在想是不是复杂度算错了,害得我一步步来痛苦地去调试 T.T
56     while(num && mul <= mod && c <= mod) {
57         if(num & 1)   mul *= c;
58         c *= c;
59         num >>= 1;
60     }
61     if(num && (mul > mod || c > mod))   return quick_mod(a[id], pow, mod) + mod;
62     else    return mul;
63 }
64
65 int main() {
66     int Case = 0;
67     init();
68     while(read(m)) {
69         read(n);
70         for(int i = 1; i <= n; ++i)
71             read(a[i]);
72         printf("Case #%d: %d\n",++Case, dfs(1,m) % m);
73     }
74     return 0;
75 }

  好久没做数论题了,果然很爽的感觉!虽然很难,虽然我还有 n 多的 XX 定理不会,不过我不会放弃这个如此吸引人的数学分支的,想当初搞 ACM 有很大原因也是因为她~

时间: 2024-08-28 15:14:56

uva 10692 Huge Mods 超大数取模的相关文章

UVA 10692 - Huge Mods(数论)

UVA 10692 - Huge Mods 题目链接 题意:求a0a1a2...mod m 思路:直接算肯定不行,利用欧拉定理ab=a(b mod phi(m) + phi(m))(b>=phi(m)),对指数进行降值处理,然后就可以利用快速幂去计算了,计算过程利用递归求解. 代码: #include <stdio.h> #include <string.h> const int N = 1005; int phi[N * 10], vis[N * 10], m, n, a[

(题目)超大数取模

问题描述:假如有一个很大的数,大到10^1000,那么求这个值对17取模的值! 1 #include <stdio.h> 2 int main() 3 { 4 char num[1001];//char数组存储 5 int i,ans=0; 6 gets(num); 7 for (i=0;num[i]!='\0';++i)//关键循环 8 ans=( ans*10+(num[i]-'0') )%17;//模拟的出原意中的数值,每次提前模17是可行的 9 printf("ans=%d\

UVA - 10692 Huge Mods (欧拉函数)

Problem X Huge Mod Input: standard input Output: standard output Time Limit: 1 second The operator for exponentiation is different from the addition, subtraction, multiplication or division operators in the sense that the default associativity for ex

UVa 10692 Huge Mods

方法:数论 其实不是很明白,为什么这个公式可行 a^b % m = a^(b%phi[m] + phi[m]) % m code: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 #include <vector> 7 #include <stack> 8

UVA 10692 Huge Mods(指数循环节)

指数循环节,由于a ^x = a ^(x % m + phi(m)) (mod m)仅在x >= phi(m)时成立,故应注意要判断 //by:Gavin http://www.cnblogs.com/IMGavin/ //指数循环节 递归处理 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include&l

hdoj 4828 卡特兰数取模

Grids Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 93    Accepted Submission(s): 25 Problem Description 度度熊近期非常喜欢玩游戏.这一天他在纸上画了一个2行N列的长方形格子. 他想把1到2N这些数依次放进去.可是为了使格子看起来优美,他想找到使每行每列都递增的方案.只是画了

hunnu11562:The Triangle Division of the Convex Polygon(第n个卡特兰数取模)

Problem description   A convex polygon with n edges can be divided into several triangles by some non-intersect diagonals. We denote d(n) is the number of the different ways to divide the convex polygon. For example,when n is 6,there are 14 different

UVA 10692 Huge Mod

Problem X Huge Mod Input: standard input Output: standard output Time Limit: 1 second The operator for exponentiation is different from the addition, subtraction, multiplication or division operators in the sense that the default associativity for ex

UVA - 11916 Emoogle Grid (离散对数取模)

You have to color an M x N (1M, N108) two dimensional grid. You will be provided K (2K108) different colors to do so. You will also be provided a list of B (0B500)list of blocked cells of this grid. You cannot color those blocked cells. A cell can be