然後怎麼做呢?斯特林數那一部分不好直接搞吧,那就弄開
推一下斯特林通項?
我們知道 {kn} 如果沒有那個集合非空的限制而且集合有序就是等於 nk
但是現在有非空的限制。我們考慮容斥: n 個有序元素劃分爲 k 個有序集合,限制至少 i 個集合是空噠,方案數 (ik)(k−i)n
容斥:{kn}=k!1i=0∑k(−1)i(ik)(k−i)n 。外面乘上的 k!1 使集合無序。
最後那個就先不管了,我們暫時只考慮前面的係數 P P===s=1∑n(s−1n−1)⋅(k−1)!si=0∑k−1(−1)i(ik−1)(k−i−1)n−ss=1∑n(s−1n−1)s⋅i=0∑k−1i!(k−i−1)!(−1)i(k−i−1)n−si=0∑k−1i!(k−i−1)!(−1)is=1∑ns(s−1n−1)(k−i−1)n−s
前面那個好弄了
搞後面那個 湊係數 湊組合恆等(挪走 s ) 湊二項式 Q=====s=1∑ns(s−1n−1)(k−i−1)n−ss=1∑n(s−1n−1)(s−1)(k−i−1)n−s+s=1∑n(s−1n−1)(k−i−1)n−s(n−1)s=2∑n(s−2n−2)(k−i−1)n−s+s=0∑n−1(sn−1)(k−i−1)n−1−s(n−1)s=0∑n−2(sn−2)(k−i−1)n−2−s+(k−i)n−1(n−1)(k−i)n−2+(k−i)n−1
則 P=i=0∑k−1i!(k−i−1)!(−1)i(k−i)n−2(k+n−i−1)
另一種思路是考慮統計每一個數對某個數的貢獻 P={kn}+(n−1){kn−1}
也一樣。
#include<cstdio>#include<iostream>#include<algorithm>#include<cstdlib>#include<cstring>#include<cmath>#include<ctime>usingnamespace std;constlonglong p =1e9+7;constint MAXN =2e5+5;int n, k;longlong ans, sum;longlong stair[MAXN];inlinelonglongqpow(longlong a,longlong b){if(b <0)return1;registerlonglong ret =1;while(b){if(b &1){
ret *= a;
ret %= p;}
a *= a;
a %= p;
b >>=1;}return ret;}inlinevoidAdjust(longlong& x){
x =(x % p)+ p;if(x >= p) x -= p;}intmain(){scanf("%d%d",&n,&k);for(registerint t, i =1; i <= n;++i){scanf("%d",&t);
sum += t;if(sum >= p) sum -= p;}
stair[0]=1;for(registerint i =1; i <= k;++i){
stair[i]= stair[i-1]* i % p;}for(registerint i =0; i < k;++i){if(i &1) ans -=qpow(k-i,n-2)*(k+n-i-1)% p *qpow(stair[i]*stair[k-i-1]%p, p-2)% p,Adjust(ans);else ans +=qpow(k-i,n-2)*(k+n-i-1)% p *qpow(stair[i]*stair[k-i-1]%p, p-2)% p, ans %= p;}printf("%I64d", ans * sum % p);return0;}