QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#404931#7754. Rolling For DaysSorting#TL 0ms0kbC++202.4kb2024-05-05 01:24:432024-05-05 01:24:44

Judging History

你现在查看的是最新测评结果

  • [2024-05-05 01:24:44]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-05-05 01:24:43]
  • 提交

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

output:


result: