题目:Mind control——http://acm.fzu.edu.cn/problem.php?pid=2303
题意:
数列1~n,后一个是前一个的下属,贿赂一个人后他和他的下属都会效忠于你,成为你的下属。求可以贿赂m次得到的下属个数的期望
思路:
得到下属人数只取决于最上面的那个人,先只考虑取最上面的人,剩下的在下面任意取。当取得的最大编号是n-m时,此时有种情况, 可以得到m个下属;其次是n-m+1,有种情况,可以得到m+1个下属。推广得到公式,利用公式和,分子可以变换成m*C(n+1, m+1),最后得到结果
m*(n+1)/(m+1)
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn = 1e5+5;
const LL mod = 1e9+7;
LL quick(LL a, LL b)
{
LL sum = 1;
while(b){
if(b&1) sum = (sum*a)%mod;
a = (a*a) % mod;
b >>= 1;
}
return sum;
}
LL n, m, t;
LL a[maxn*10];
int main()
{
for(int i=1; i<=1e6+2; i++) a[i] = quick(i, mod-2);
cin >> t;
while(t --){
scanf("%lld%lld", &n, &m);
printf("%lld\n", ((m*(n+1))%mod*a[m+1]) % mod );
}
}