HDU 5226 Tom and matrix(组合数学+Lucas定理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5226

题意:给一个矩阵a,a[i][j] = C(i,j)(i>=j) or 0(i < j),求(x1,y1),(x2,y2)这个子矩阵里面的所有数的和。

思路:首先可以推导出一个公式C(n,i)+C(n + 1,i)+...+C(m,i) = C(m + 1,i + 1)

知道了这个公式,就可以将子矩阵里每行(或每列)的和值表示成组合数的差值,现在的关键是求出C(n,m)(mod p).

由于n和m可能很大,p很小,不能直接求,要借助Lucas定理。关于Lucas定理,可参考:http://www.cnblogs.com/zxndgv/archive/2011/09/17/2179591.html。

code:

 1 #include <cstdio>
 2 typedef __int64 LL;
 3 const int MAXN = 100005;
 4 int p;
 5 LL fac[MAXN];
 6
 7 // 得到阶乘  fac[i] = i! % p
 8 void GetFact()
 9 {
10     fac[0] = 1;
11     for (LL i = 1; i < MAXN; ++i)
12         fac[i] = fac[i - 1] * i % p;
13 }
14
15 // 快速模幂 a^b % p
16 LL Pow(LL a, LL b)
17 {
18     LL temp = a % p;
19     LL ret = 1;
20     while (b)
21     {
22         if (b & 1) ret = ret * temp % p;
23         temp = temp * temp % p;
24         b >>= 1;
25     }
26     return ret;
27 }
28
29 /*
30 欧拉定理求逆元
31 (a / b) (mod p) = (a * x) (mod p) x表示b的逆元 并且 b * x = 1 (mod p) 只有b和p互质才存在逆元
32
33 b * x = 1 (mod p) x是b关于p的逆元
34
35 b^phi(p) = 1 (mod p)
36
37 b * b^(phi(p) - 1) (mod p) = b * x (mod p)
38
39 x = b^(phi(p) - 1) = b^(p - 2)
40
41 (a / b) (mod p) = (a * x) (mod p) = (a * b^(p - 2)) (mod p)
42
43 经过上面的推导,得出:
44
45 (a / b) (mod p) = (a * b^(p - 2)) (mod p) (b 和 p互质)
46
47 */
48 LL Cal(LL n, LL m)
49 {
50     if (m > n) return 0;
51     return fac[n] * Pow(fac[m] * fac[n - m], p - 2) % p;
52 }
53
54 LL Lucas(LL n, LL m)
55 {
56     if (m == 0) return 1;
57     return Cal(n % p, m % p) * Lucas(n / p, m / p) % p;
58 }
59
60 int main()
61 {
62     int x1, y1, x2, y2;
63     while (scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &p) == 5)
64     {
65         if (x2 < y1)    // 预判 子矩阵全部0值区域
66         {
67             printf("0\n");
68             continue;
69         }
70         if (x2 == y1)   // 预判 子矩阵只有右上角值为1,其余为0
71         {
72             printf("1\n");
73             continue;
74         }
75         GetFact();
76         if (x1 < y1) x1 = y1;
77         if (y2 > x2) y2 = x2;
78         LL ans = 0;
79         for (int i = y1; i <= y2; ++i)
80         {
81             if (i > x1)
82                 ans = (ans + Lucas(x2 + 1, i + 1)) % p;
83             else
84                 ans = (ans + Lucas(x2 + 1, i + 1) - Lucas(x1 + 1, i + 1) + Lucas(x1, i)) % p;
85         }
86         printf("%I64d\n", ans);
87     }
88     return 0;
89 }
时间: 2024-10-11 10:35:24

HDU 5226 Tom and matrix(组合数学+Lucas定理)的相关文章

hdu 5226 Tom and matrix

题意: Tom放学回家的路上,看到天空中出现一个矩阵.Tom发现,如果矩阵的行.列从0开始标号,第i行第j列的数记为a[i][j],那么a[i][j]=C(i,j) 如果i < j,那么a[i][j]=0 Tom突发奇想,想求一个矩形范围((x1,y1),(x2,y2))内所有数的和.Tom急着回家,当然不会自己算,所以就把任务交给你了. 因为数可能很大,答案对一个质数p取模. 限制: 0 <= x1 <= x2 <=1e5 0 <= y1 <= y2 <=1e5

组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix

Tom and matrix Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=5226 Mean: 题意很简单,略. analyse: 直接可以用Lucas定理+快速幂水过的,但是我却作死的用了另一种方法. 方法一:Lucas定理+快速幂水过 方法二:首先问题可以转化为求(0,0),(n,m)这个子矩阵的所有数之和.画个图容易得到一个做法,对于n<=m,答案就是2^0+2^1+...+2^m=2^(m+1)-1,对于n>m

HDU 4349 Xiao Ming&#39;s Hope lucas定理

Xiao Ming's Hope Time Limit:1000MS     Memory Limit:32768KB Description Xiao Ming likes counting numbers very much, especially he is fond of counting odd numbers. Maybe he thinks it is the best way to show he is alone without a girl friend. The day 2

hdu 4349 Xiao Ming&#39;s Hope (Lucas定理推导)

题意:求C (n,0),C (n,1),C (n,2)...C (n,n).奇数的个数 思路:我们分析C(n,m)%2,那么由Lucas定理可知,n和m可以写成二进制的形式,假设n=1001101,那么m是0~1001101,我们知道C(0,1)=0,因此如果n=1001101的0对应位置的m二进制位为1那么C(n,m) % 2==0,因此m对应n为0的位置只能填0,而1的位置填0,填1都是1(C(1,0)=C(1,1)=1),不影响结果为奇数,并且保证不会出n的范围,因此所有的情况即是n中1位

HDU 3037 Saving Beans (数论,Lucas定理)

题意:问用不超过 m 颗种子放到 n 棵树中,有多少种方法. 析:题意可以转化为 x1 + x2 + .. + xn = m,有多少种解,然后运用组合的知识就能得到答案就是 C(n+m, m). 然后就求这个值,直接求肯定不好求,所以我们可以运用Lucas定理,来分解这个组合数,也就是Lucas(n,m,p)=C(n%p,m%p)* Lucas(n/p,m/p,p). 然后再根据费马小定理就能做了. 代码如下: 第一种: #pragma comment(linker, "/STACK:10240

组合数学lucas定理 BZOJ2982 combination

2982: combination Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 597  Solved: 357[Submit][Status][Discuss] Description LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样.那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值.(1<=m<=n<=200,000,000) Inpu

HDU 3304 Interesting Yang Yui Triangle lucas定理

输入p n 求杨辉三角的第n+1行不能被p整除的数有多少个 Lucas定理: A.B是非负整数,p是质数.AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]. 则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0])  mod p同余 即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p),在存在i.b[i]>a[i]时,mod值为0,所以必然整除.当对于全部i,b

[HDU 3461] Saving Beans &amp; 组合计数Lucas定理模板

Saving Beans Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description Although winter is far away, squirrels have to work day and night to save beans. They need plenty of food to get through those long cold

BZOJ 2111 ZJOI2010 Perm 排列计数 组合数学+Lucas定理

题目大意:求1~n的排列能组成多少种小根堆 考虑一个1~i的排列所构成的堆,l为左儿子大小,r为右儿子的大小 那么1一定是堆顶 左儿子和右儿子分别是一个堆 显然如果选出l个数给左儿子 那么左儿子的方案数显然是f[l],右儿子的方案数为f[r] 于是有f[i]=C(i-1,l)*f[l]*f[r] 于是我们线性筛处理出阶乘和阶乘的逆元 代入即可得到WA 原因是这题n可以大于p 此时要用到Lucas定理 坑死了 #include <cstdio> #include <cstring>