1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| ##河南省2021CCPC 数学期望 (组合数学+乘法逆元)
每个技能性质相同,只需求出一个技能的贡献值*m即可;
枚举技能使用1--n次的贡献值,对于每个贡献值*m
当前技能使用i次,则剩余(m-1)个技能,占用(n-i)个位置, #pragma GCC optimize(3,"Ofast","inline") #pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; #define endl '\n' typedef long long ll; typedef long long LL; #define int long long #define ld long double const int N=1e5+10; int n,a[100010],m; const int mod=1e9+7; int exgcd(int a,int b,int &x,int &y){ if (!b) { x = 1, y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } ll inverse(int a,int p,int ok){ int x=0,y=0; int res=exgcd(a,p,x,y); if(res==1) res=(x+p)%p; else{res=-1;} return res; } int fact[N], infact[N]; int qmi(int a, int k, int p) { int res = 1; while (k) { if (k & 1) res = (LL)res * a % p; a = (LL)a * a % p; k >>= 1; } return res; } void init(){ fact[0] = infact[0] = 1; for (int i = 1; i < N; i ++ ) { fact[i] = (LL)fact[i - 1] * i % mod; infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod; } } int c(int a,int b){ return fact[a] * infact[b] % mod * infact[a - b] % mod; } void solve() { cin>>n>>m; int res=0; for(int i=1;i<=n;i++){ res=res+(LL)i*i%mod*m%mod*c(n,i)%mod*qmi(m-1,n-i,mod); res=res%mod; } res=res*inverse(qmi(m,n,mod),mod,0)%mod; cout<<res<<endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); init(); int t; cin>>t; while(t--) { solve(); } return 0; }
|