toj 4111 组合数取模 暴力分解

题目大意:组合数取模,n和m并不算大,p比较大且是合数。

思路:暴力分解+快速幂

注:暴力也是有区别的,分解质因数时可以用以下work函数,写的非常巧妙,摘录自互联网。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4
 5 typedef long long ll;
 6 const ll mod = 1ll << 32;
 7 const int N = 1000001;
 8 const int M = 100007;
 9 bool is_prime[N];
10 int prime[M];
11 int p;
12
13 void get()
14 {
15     memset( is_prime, true, sizeof(is_prime) );
16     is_prime[0] = is_prime[1] = false;
17     for ( int i = 2; i < N; i++ )
18     {
19         if ( is_prime[i] )
20         {
21             int j = i * i;
22             if ( j >= N ) break;
23             do
24             {
25                 is_prime[j] = false;
26                 j += i;
27             } while ( j < N );
28         }
29     }
30     p = 0;
31     for ( int i = 0; i < N; i++ )
32     {
33         if ( is_prime[i] )
34         {
35             prime[p++] = i;
36         }
37     }
38 }
39
40 ll pow_mod( ll a, ll n )
41 {
42     ll ans = 1;
43     a = a % mod;
44     while ( n )
45     {
46         if ( n & 1 )
47         {
48             ans = ans * a % mod;
49         }
50         n = n >> 1;
51         a = a * a % mod;
52     }
53     return ans;
54 }
55
56 ll work( ll n, ll q )
57 {
58     ll ans = 0;
59     while ( n )
60     {
61         ans += n / q;
62         n /= q;
63     }
64     return ans;
65 }
66
67 ll c( ll n, ll m )
68 {
69     ll ans = 1;
70     for ( int i = 0; i < p && prime[i] <= n; i++ )
71     {
72         ll x = work( n, prime[i] );
73         ll y = work( n - m, prime[i] );
74         ll z = work( m, prime[i] );
75         x = x - ( y + z );
76         ans = ans * pow_mod( prime[i], x ) % mod;
77     }
78     return ans;
79 }
80
81 int main ()
82 {
83     get();
84     int t;
85     cin >> t;
86     while ( t-- )
87     {
88         ll n, m;
89         cin >> n >> m;
90         cout << c( n, m ) << endl;
91     }
92     return 0;
93 }
时间: 2024-10-19 17:25:01

toj 4111 组合数取模 暴力分解的相关文章

组合数取模Lucas定理及快速幂取模

组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以直接用杨辉三角递推,边做加法边取模. (2) ,   ,并且是素数 本文针对该取值范围较大又不太大的情况(2)进行讨论. 这个问题可以使用Lucas定理,定理描述: 其中 这样将组合数的求解分解为小问题的乘积,下面考虑计算C(ni, mi) %p. 已知C(n, m) mod p = n!/(m!(

组合数取模终极版

以前讲述过很多组合数取模问题,详见:http://blog.csdn.net/acdreamers/article/details/8037918 今天,我们继续学习一些稍有难度的组合数取模问题,比如大组合数对合数取模,求大组合数的最后位数字等等. 首先来看组合数对合数取模问题 问题:求的值,其中和,并且是合数. 分析:先把素因子分解,然后转化为求,这里为素数,然后用CRT合并.所以现在重点来研究 如何求的值.这个问题AekdyCoin大神已经详细讲述了,如下链接     链接:http://h

排列组合+组合数取模 HDU 5894

1 // 排列组合+组合数取模 HDU 5894 2 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 3 // 思路: 4 // 定好m个人 相邻人之间k个座位 剩下就剩n-(m+1)*k个座位 5 // 剩下座位去插m个不同的盒子==就等价n个相同的球放m个不同的盒子 6 // 然后组合数出来了 7 // 乘n的话是枚举座位,除m是去掉枚举第一个座位的时候,剩下人相邻的座位相对不变的情况 8 9 #include <iostream> 10 #incl

大组合数取模之lucas定理模板,1&lt;=n&lt;=m&lt;=1e9,1&lt;p&lt;=1e6,p必须为素数

typedef long long ll; /********************************** 大组合数取模之lucas定理模板,1<=n<=m<=1e9,1<p<=1e6,p必须为素数 输入:C(n,m)%p 调用lucas(n,m,p) 复杂度:min(m,p)*log(m) ***********************************/ //ax + by = gcd(a,b) //传入固定值a,b.放回 d=gcd(a,b), x , y

hdu 3037 Saving Beans 组合数取模模板题。。

Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2707    Accepted Submission(s): 1014 Problem Description Although winter is far away, squirrels have to work day and night to save b

[BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】

题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 m 减去 Ai - 1 ,相当于将这一部分固定分给 xi,就转化为无限制的情况了. 如果有一些限制条件是 xi <= Ai 呢?直接来求就不行了,但是注意到这样的限制不超过 8 个,我们可以使用容斥原理来求. 考虑容斥:考虑哪些限制条件被违反了,也就是说,有哪些限制为 xi <= Ai 却是 xi

大组合数取模

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1119 考虑从(1,1)->(n,m)必定会向下走n-1步,向右走m-1步,那么总的走法是C(n-1+m-1,m-1). 关于组合数取模:大神博客:http://blog.csdn.net/acdreamers/article/details/8037918 1 #include <iostream> 2 #include <string.h> 3 #

BZOJ 3129 [Sdoi2013]方程 不定方程解的个数+组合数取模

题意:链接 方法:不定方程解的个数+组合数取模 解析: 先看n1与n2的部分的限制. 对于后半部分的限制来说,我们直接减去An1+i?1就可以转化一下求正整数解. 但是前半部分呢? 跟上一道猴子那个很像. 所以我们容斥搞就行了. 但是这道题好像不好写的地方不在这? 这题TMD不就是礼物吗! 大组合数取模如何取? 请参见我<BZOJ 礼物>的题解. 另外吐槽题干 明明是X1+X2+-+Xn=m 并不是小于等于 代码: #include <cstdio> #include <cs

Lucas定理--大组合数取模 学习笔记

维基百科:https://en.wikipedia.org/wiki/Lucas%27_theorem?setlang=zh 参考:http://blog.csdn.net/pi9nc/article/details/9615359 http://hi.baidu.com/lq731371663/item/d7261b0b26e974faa010340f http://hi.baidu.com/j_mat/item/8e3a891c258c4fe9dceecaba 综合以上参考,我做的一下总结: