1. 程式人生 > 其它 >「acmhdu - 6314」Matrix

「acmhdu - 6314」Matrix

link。

首先將問題弱化為 1-d,我們待定容斥係數 \(f_i\),可以寫出答案的式子:\(\sum\limits_{i=a}^nf_i\binom{n}{i}2^{n-i}\)。解釋就是,我們想讓 \(\binom{n}{i}2^{n-i}\) 達到“至少”的效果,但是明顯會算重,所以通過這個容斥係數 \(f_i\) 達到“恰好”的效果,於是原題“至少”的答案就是這個。

每一個“恰好” \(i\) 個的方案數在最終的答案中的貢獻次數為 \(1\),也就是說 \(\sum\limits_{j=a}^if_j\binom{i}{j}=1\)。這個的意思就是如果至少有 \(i\) 的方案數重了,那麼它一定是從前面開始重的(就是說 \(1,\dots,i-1\)

的隨便擺的部分跟它重了),所以從前面開始容斥。

然後就好算了,可以直接得出 \(f_i=\sum\limits_{j=a}^{i-1}f_j\binom{i-1}{j-1}\),或者你也可以用下吸收公式推式子。

但實際上這個題還有一些常數的優化,具體可以看看 Siyuan 的部落格。

#include<bits/stdc++.h>
#define il __inline__ __attribute__((always_inline))
constexpr int kMod=998244353;
__int128 sum;
int n,m,A,B,i,j,k;
int coef[2][3100],pw[9000100],bin[3100][3100];
il void MCase() {
  for(k=0; k<2; ++k) {
    coef[k][0]=1;
    for(int i=(k?B:A); i<=(k?m:n); ++i) coef[k][i]=1ll*(((i-(k?B:A))&1)?-1:1)*bin[i-1][(k?B:A)-1]%kMod*bin[k?m:n][i]%kMod;
  }
  int res=0;
  for(i=A; i<=n; ++i)
    for(j=B; j<=m; ++j) (res+=1ll*coef[0][i]*coef[1][j]%kMod*pw[(n-i)*(m-j)]%kMod)%=kMod;
  std::printf("%d\n",res<0?res+kMod:res);
}
signed main(int argc,char const* argv[]) {
  pw[0]=1;
  for(i=1; i<9000100; ++i) pw[i]=1ll*pw[i-1]*2%kMod;
  bin[0][0]=1;
  for(i=1; i<3100; ++i) {
    bin[i][0]=1;
    for(j=1; j<=i; ++j) bin[i][j]=(bin[i-1][j]+bin[i-1][j-1])%kMod;
  }
  for(; ~std::scanf("%d%d%d%d",&n,&m,&A,&B);) MCase();
  return 0;
}