Description
Solution
- 剛開始看到矩陣求逆後發現連裸的矩陣求逆我都不會(其實我去年應該是學過的。。。),只會一發n6的暴力對n2個點進行高斯消元。
- 實際上,矩陣求逆有一種很好做的n3高斯消元。
- 對於矩陣,將它變爲單元矩陣,同時根據的操作,同步地操作一個,因爲矩陣的操作是互逆的,所以在經過相同的操作後就變成了
- 考慮對於這個Pascal矩陣做同樣的操作。
- 注意到這個矩陣已經是一個三角形了,並且對於同一列,它們的分母都是一樣的,所以在消元的時候可以忽略這個。那麼只需要將這個矩陣消成一個對角線的1就好了。
- 然後因爲這個矩陣,這個其實是二項式反演的基本式子,它的逆矩陣就是二項式反演的容斥係數.
- 然後再把乘上去就好了。
- 最後計算每一列的平方和。即。
- 結論。
小證明
- 簡單的理解成即將2n個數分成兩半,前一半選i個,後一半選n-i個,因爲枚舉了i,所以相當於是2n裏面選n個。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxm 2000005
#define ll long long
#define mo 1000000007
using namespace std;
int n,m,i,j,k;
ll fct[maxm],ift[maxm],ans;
ll ksm(ll x,ll y){
ll s=1;
for(;y;y/=2,x=x*x%mo) if (y&1)
s=s*x%mo;
return s;
}
ll C(int n,int m){return fct[n]*ift[m]%mo*ift[n-m]%mo;}
int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%d%d",&n,&m);
fct[0]=fct[1]=1;for(i=2;i<maxm;i++) fct[i]=fct[i-1]*i%mo;
ift[maxm-1]=ksm(fct[maxm-1],mo-2);
for(i=maxm-2;i>=0;i--) ift[i]=ift[i+1]*(i+1)%mo;
for(i=1;i<=n;i++) ans+=ksm(i,2*m)*(C(2*i,i)-1)%mo;
printf("%lld",ans%mo);
}