QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#404931 | #7754. Rolling For Days | Sorting# | TL | 0ms | 0kb | C++20 | 2.4kb | 2024-05-05 01:24:43 | 2024-05-05 01:24:44 |
answer
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <array>
#include <iomanip>
#include <queue>
#include <stack>
#include <numeric>
#include <cassert>
#include <cmath>
using namespace std;
typedef long long ll;
const ll mod=998244353;
int n,m;
const int iu=2000;
ll f[2005],inf[2005];
ll C[2005][2005];
inline ll fast_mod(ll x){
return x >= mod ? (x % mod) : x;
}
ll pw(ll x,ll y){
ll ans = 1;
while(y){
if(y % 4 == 1) ans = fast_mod(x * pw(x, y - 1));
if(y % 4 == 2) ans = fast_mod(x * fast_mod(x * pw(x, y - 2)));
if(y % 4 == 3) ans = fast_mod(x * fast_mod(x * fast_mod(x * pw(x, y - 3))));
y /= 2;
x = fast_mod(x * x);
x = fast_mod(x * x);
}
return ans;
}
int a[15],b[15];
ll ff[4096][1005];
int deg[4096];
ll dp[4096][1005];
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin >> n >> m;
for(int i=0; i<m ;i++) cin >> a[i];
int ST=0;
for(int i=0; i<m ;i++){
cin >> b[i];
if(b[i]==0) ST|=1<<i;
}
C[0][0]=1;f[0]=inf[0]=1;
for(int i=1; i<=iu ;i++){
f[i]=f[i-1]*i%mod;
inf[i]=pw(f[i],mod-2);
C[i][0]=1;
for(int j=1; j<=i ;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}
ff[0][0]=1;
deg[0]=0;
for(int i=1; i<(1<<m) ;i++){
if(i&ST) continue;
int w=i&-i;
int g=0;
while(w!=(1<<g)) ++g;
deg[i]=deg[i^w]+b[g]-1;
for(int j=0; j<=deg[i^w] ;j++){
for(int k=0; k<b[g] ;k++){
ff[i][j+k]=fast_mod(ff[i][j+k]+ff[i^w][j]*C[a[g]][k]);
}
}
}
dp[ST][0]=1;
ll ans=0;
for(int i=0; i<(1<<m)-1 ;i++){
for(int j=0; j<=n ;j++){
if(dp[i][j]==0) continue;
int can=0;
int trash=0;
int done=0;
for(int k=0; k<m ;k++){
if((i>>k)&1) trash+=a[k]-b[k],done+=b[k];
else can+=a[k];
}
can-=j-done;
ll cost=(trash*f[can-1]%mod*inf[can]%mod+1);
ans=(ans+cost*dp[i][j])%mod;
ll ways=1;
int mask=((1<<m)-1)^i;
for(int k=0; k<m ;k++){//calculate ways to complete set k
if((i>>k)&1) continue;
int g=k;
if(j-done<b[g]-1) continue;
ll num=ff[mask^(1<<k)][j-done-b[g]+1]*C[a[g]][b[g]-1]%mod;
ll den=ff[mask][j-done];
ll prob=(a[g]-b[g]+1)*f[can-1]%mod*inf[can]%mod;
prob=num*prob%mod*pw(den,mod-2)%mod;
dp[i|(1<<k)][j+1]=(dp[i|(1<<k)][j+1]+prob*dp[i][j])%mod;
ways=(ways+mod-prob)%mod;
}
dp[i][j+1]=(dp[i][j+1]+dp[i][j]*ways)%mod;
}
}
cout << ans << '\n';
}
詳細信息
Test #1:
score: 0
Time Limit Exceeded
input:
2 2 1 1 1 1