HDU 3123 GCC(同余模定理)

GCC

大意:给一个n,一个m,求(0! + 1! + 2! + 3! + 4! + ... + n!)%m     0 <= n < 10^100         0 < m < 1000000   

思路:n可以达到10^100,很明显不能直接处理。但是发现只要n>m,那么m!+(m+1)!+...+n!这些项都是可以被m整除的,要对m求余,只需要找比m小的阶乘即可,而m的范围为1000000,在O(m)的复杂度下是可以完成的。所以只需判断n是否大于m,若大于m,则取m-1即可,若小于m则不变。

 1 #include <map>
 2 #include <queue>
 3 #include <stack>
 4 #include <math.h>
 5 #include <stdio.h>
 6 #include <string.h>
 7 #include <iostream>
 8 #include <algorithm>
 9 #define LL long long
10 using namespace std;
11 
12 void run()
13 {
14     int n, m;
15     char s[1010];
16     scanf("%d", &n);
17     while(n--)
18     {
19         int t = 0;
20         scanf("%s%d%*c", s, &m);           
21         ///输入可能是很大的数据(10^100)所以要用字符串处理
22         int len = strlen(s);
23         if(len >= 7)                 ///判断输入是否大于1000000
24             t = m-1;
25         else
26         {
27             int p = 1;
28             for(int i = len-1; i >= 0; i--)
29             {
30                 t += (s[i]-'0')*p;
31                 p *= 10;
32             }
33         }
34         if(t >= m)
35             t = m-1;
36         LL temp = 1, ans = 1;
37         for(LL i = 1; i <= t; i++)                  ///处理阶乘之和
38         {
39             temp = (temp*i)%m;
40             ans = (ans+temp)%m;
41         }
42         ans %= m;
43         printf("%lld\n", ans);
44     }
45 }
46 
47 int main(void)
48 {
49     run();
50 
51     return 0;
52 }
GCC

 

同余定理:

1)a≡a(mod d)
2)a≡b(mod d)→b≡a(mod d)
3)(a≡b(mod d),b≡c(mod d))→a≡c(mod d)
  如果a≡x(mod d),b≡m(mod d),则
4)a+b≡x+m (mod d)
5)a-b≡x-m (mod d)
6)a*b≡x*m (mod d )
7)a≡b(mod d)则a-b整除d

 

 

同余定理具有可加、可减、可乘、乘方性:  

(A + B) % C = (A % C + B % C) % C;

(A - B) % C = (A % C - B % C) % C;

(A * B) % C = (A % C * B % C) % C;

(A ^ B) % C = (A^N + B^N) % C;

 

注:写的时候脑残了,感谢大神的指教,感谢!

posted @ 2013-11-04 23:47  GLSilence  阅读(446)  评论(2编辑  收藏  举报