通过费马小定理求组合数(防止越界,因为做除法之前不能够取余)
2014-07-24 00:04
288 查看
转载自:http://blog.csdn.net/xuezhongfenfei/article/details/10100651
费马小定理:a^(p-1) ≡1(mod p)a和p是互质的(p为质数)。 那么对于任意的求a^m%p则可以转换为a^(m%(p-1))%p,可以使复杂度很高的求此方的进行化简
欧拉函数上的应用就是: a,m互质,a^φ(m)≡1(mod m)//(φ(m)为欧拉函数,表示的是m之前与m互质的正整数的个数,而如果m为质数的话则m-1就为m的欧拉函数值,这又到了费马小定理)
求排列组合中的C(n,m),如果n和m都很大,而且取得的值是要模上mod,那么如果仍然按照n!/(m!*(n-m)!)算的话肯定就会爆,如果边去摸边算的话结果就会不对,那么应该怎么算呢?
转换为n!*(m!)^(md-2)*((n-m)!^mod-2);mod-2也可以为mod的欧拉函数值-1,这里暂且设mod为质数
因为求的是n!/(m!*(n-m)!),则可以转换为n!*(m!)^(-1)*(n-m)!^-1,
n!*m!^(-1)*(n-m)!^(-1) *m!^(mod-1) *(n-m)!^(mod-1),因为后两项都为1,所以乘后结果不变,然后就转换为了上面的式子,这样就不用担心除法的时候因为取模的问题了!
有一道例题,hdu4869 ,第一场多校第九题。记录一下。
费马小定理:a^(p-1) ≡1(mod p)a和p是互质的(p为质数)。 那么对于任意的求a^m%p则可以转换为a^(m%(p-1))%p,可以使复杂度很高的求此方的进行化简
欧拉函数上的应用就是: a,m互质,a^φ(m)≡1(mod m)//(φ(m)为欧拉函数,表示的是m之前与m互质的正整数的个数,而如果m为质数的话则m-1就为m的欧拉函数值,这又到了费马小定理)
求排列组合中的C(n,m),如果n和m都很大,而且取得的值是要模上mod,那么如果仍然按照n!/(m!*(n-m)!)算的话肯定就会爆,如果边去摸边算的话结果就会不对,那么应该怎么算呢?
转换为n!*(m!)^(md-2)*((n-m)!^mod-2);mod-2也可以为mod的欧拉函数值-1,这里暂且设mod为质数
因为求的是n!/(m!*(n-m)!),则可以转换为n!*(m!)^(-1)*(n-m)!^-1,
n!*m!^(-1)*(n-m)!^(-1) *m!^(mod-1) *(n-m)!^(mod-1),因为后两项都为1,所以乘后结果不变,然后就转换为了上面的式子,这样就不用担心除法的时候因为取模的问题了!
有一道例题,hdu4869 ,第一场多校第九题。记录一下。
/***********************************************\ |Author: Messyidea |Created Time: 2014-7-22 13:48:33 |File Name: b.cpp |Description: \***********************************************/ #include <iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <string> #include <cstring> #include <algorithm> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #define L(rt) (rt<<1) #define R(rt) (rt<<1|1) #define mset(l,n) memset(l,n,sizeof(l)) #define rep(i,n) for(int i=0;i<n;++i) #define maxx(a) memset(a, 0x3f, sizeof(a)) #define zero(a) memset(a, 0, sizeof(a)) #define srep(i,n) for(int i = 1;i <= n;i ++) #define MP make_pair const int inf=0x3f3f3f3f ; const double eps=1e-8 ; const double pi=acos (-1.0); typedef long long ll; #define mod 1000000009 #define LL long long using namespace std; int n,m; ll f[100005]; LL extend_gcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1; y=0; return a; } LL gcd=extend_gcd(b,a%b,x,y); LL t=x; x=y; y=t-a/b*x; return gcd; } LL Get_Inverse(LL num) { LL x,y; extend_gcd(num,mod,x,y); return (x%mod+mod)%mod; } LL Combine(LL n,LL m)//计算组合数C(n,m) { LL t1=1,t2=1; for(LL i=n;i>m;i--) { t1=(t1*i)%mod; t2=(t2*(i-m))%mod; } return t1*Get_Inverse(t2)%mod; } void pre(){ int i; f[0] = 1; for(int i=1;i<100005;++i){ f[i] = (f[i-1]*i)%mod; } } int ma[100005]; int da[100005]; int l,r; ll quickmod(ll x,ll y){ ll res = 1; while(y>0){ if(y&1) res = res * x % mod; x = x * x % mod; y>>=1; } return res; } void solve(){ l = r = m; int num = 0; int p; if(m % 2 == 0) { p = 0; } else { p = 1; } rep(i,n){ int tl = l,tr = r; if(ma[i] % 2 == 1) p = p ^ 1; num = 0; if(m - tl >= ma[i]) da[num ++] = tl + ma[i]; if(tl >= ma[i]) da[num++] = tl - ma[i]; if(m - tl < ma[i]){ da[num ++] = m-(ma[i] - (m-tl)); } if(tl < ma[i]) { da[num ++] = ma[i] - tl; } if(m - tr >= ma[i]) da[num ++] = tr + ma[i]; if(tr >= ma[i]) da[num++] = tr - ma[i]; if(m - tr < ma[i]){ da[num ++] = m-(ma[i] - (m-tr)); } if(tr < ma[i]) { da[num ++] = ma[i] - tr; } if(tr >= ma[i] && tl <= ma[i]){ if(p == 1) da[num ++] = 1; else da[num ++] = 0; } if(tr + ma[i] >= m && tl + ma[i] <= m ){ if(p == 1){ if(m % 2 == 0) da[num++] = m-1; else da[num ++] = m; } else { if(m % 2 == 0) da[num ++] = m; else da[num ++] = m-1; } } sort(da,da+num); //rep(i,num) cout<<da[i]<<" ";cout<<endl; tl = da[0];tr = da[num-1]; l = tl;r = tr; } LL ans = 0; ans = 0; LL tp = Combine(m,l); //cout<<l<<" "<<r<<endl; for(int i = l;i <= r;i += 2){ ans += f[m]*quickmod(f[m-i],mod-2)%mod*quickmod(f[i],mod-2)%mod; ans %= mod; } printf("%lld\n",ans); } int main() { //freopen("input.txt","r",stdin); pre(); while(~scanf("%d%d",&n,&m)){ rep(i,n) scanf("%d",&ma[i]); solve(); } return 0; }
相关文章推荐
- Django的POST请求时因为开启防止csrf,报403错误,及四种解决方法
- 通过Spring @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
- SQL或HQL预编译语句,能够防止SQL注入,但是不能处理%和_特殊字符
- STM32通过读取芯片唯一ID号来实现程序的保护,防止被抄袭
- 如何破解Ubuntu root密码及防止别人通过单用户模式修改密码
- 保护您的应用,防止黑客攻击(通过静态链接防止逆向工程效果会好得多)
- Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。
- 【原创】JAVA通过过滤器防止脚本注入
- linux复习笔记第一篇 - 可能会很混乱,因为是看之前的笔记粘贴一遍
- 51nod1119(除法取模/费马小定理求组合数)
- 能够通过保存副本的方式复制族表吗?
- Objective-c防止数组越界而崩溃(全局效果)
- 通过Spring @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
- 大整数除法(取模和取余)
- 最近用plsql通过 @sql语句路径的方式 因为手贱导致sql文件执行不下去的问题
- 通过HttpModule、httpHandlers防止SQL注入式攻击
- 防止通过URL下载文件
- iOS中防止数组越界之后发生崩溃
- springMvc通过iframe文件上传以及回显,文件上传的文件夹定义到webapps外面防止重新部署文件丢失
- 为什么这样能够防止头文件重复调用?