fzu 2282(错位排列+逆元+快速幂函数)
2017-07-24 09:18
363 查看
Problem 2282 Wand
Accept: 30 Submit: 94
Time Limit: 1000 mSec Memory Limit : 262144 KB
Problem Description
N wizards are attending a meeting. Everyone has his own magic wand. N magic wands was put in a line, numbered from 1 to n(Wand_i owned by wizard_i). After the meeting, n wizards will take a wand one by one in the order of 1 to n. A boring wizard decidedto reorder the wands. He is wondering how many ways to reorder the wands so that at least k wizards can get his own wand.
For example, n=3. Initially, the wands are w1 w2 w3. After reordering, the wands become w2 w1 w3. So, wizard 1 will take w2, wizard 2 will take w1, wizard 3 will take w3, only wizard 3 get his own wand.
Input
First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.For each test case: Two number n and k.
1<=n <=10000.1<=k<=100. k<=n.
Output
For each test case, output the answer mod 1000000007(10^9 + 7).
Sample Input
21 1
3 1
Sample Output
14
题意:给你一个n代表编号为1-n的有序的n个人,一个k,重新排序之后,询问至少有k人在自己原来位置的方案数。
思路:首先n个人排序,每个人都不在自己原来位置的可能有F(n)=(i-1)*(F(n-1)+F(n-2)) (n>=2) 特殊的,F(0)=1,F(1)=0;
然后考虑每次错排的组合数:C(n,i)= i!/(i!*(n-i)!),对于(A/B)mod C,找到B的逆元b=B^-1,求出(A*b)%C即可。
由费马小定理:B
关于 P 的逆元为 B^(p-2);
费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为:
假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。所以,a^-1*a=1=a^(p-1),所以:a^-1=a^(p-2);
代码:
#include<cstdio> #include<vector> #include<iostream> const int mod = 1e9 + 7; const int maxn = 10005; typedef long long LL; using namespace std; LL dp[maxn]; LL inv[maxn]; int n,k; LL pri[maxn]; LL ni[maxn]; LL pow(LL a,int b) { LL ans=1,base=a; while (b>0) { if (b%2==1) ans=(base*ans)%mod; base=(base*base)%mod; b/=2; } return ans; } void s() //打表 { pri[0]=1; ni[0]=1; for (int i=1;i<=maxn ;i++) { pri[i]=pri[i-1]*i%mod; //N! ni[i]=pow(pri[i],mod-2); } } int main() { s(); int T; scanf("%d", &T); dp[0]=1,dp[1] = 0; for(int i = 2; i <= maxn; i++) { dp[i] = ((i - 1) * (dp[i - 1] + dp[i - 2])) % mod; } while(T--) { LL ans=1; scanf("%d%d", &n, &k); int cnt = n - k; if(cnt==0) { puts("1"); continue; } if(cnt==1) { puts("0"); continue; } for(int i=2;i<=cnt;i++) { LL sum=((pri *ni[i]%mod)*ni[n-i])%mod; //printf("%lld\n",sum); ans+=(sum*dp[i])%mod; } printf("%lld\n",ans%mod); } return 0; }
相关文章推荐
- 【BZOJ4517】【Sdoi2016】排列计数 线性逆元 错位排列
- BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)
- FZU2282-组合数-逆元
- BZOJ 4517 浅谈错位排列组合计数
- [ACM] hdu 2048 神、上帝以及老天爷 (错位排列公式)
- 全错位排列
- [BZOJ4517][SDOI2016]排列计数(错位排列)
- 全错位排列
- hdu5651xiaoxin juju needs help 乘法的逆元||重复元素的排列
- FZU 2282 错排
- HDU_2049——部分错位排列,概率论
- [ACM] hdu 2048 神、上帝以及老天爷 (错位排列公式)
- FZU 2282 错排
- 【坑爹系列】常见的图片排列错位问题-根源分析及解决方案
- FZU 2019 排列
- [ACM] hdu 2048 神、上帝以及老天爷 (错位排列公式)
- 错位排列
- FZU 2282 错排
- 【FZU - 2282】 Wand 【错排+费马小定理】
- 广东工业大学2017新生赛(决赛)-网络同步赛 1007 白色相簿的季节【全错位排列】