QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#311093#7754. Rolling For Daysarnold518WA 0ms36312kbC++173.4kb2024-01-21 21:40:422024-01-21 21:40:43

Judging History

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

  • [2024-01-21 21:40:43]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:36312kb
  • [2024-01-21 21:40:42]
  • 提交

answer

#include <bits/stdc++.h>
#define ff first
#define ss second
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MOD = 998244353;
struct mint
{
	int x;
	mint() : x(0) {}
	mint(int _x) : x(_x) {}
	mint operator + (int ot) const { return x+ot>=MOD ? x+ot-MOD : x+ot; }
	mint operator - () const { return x ? MOD-x : 0; }
	mint operator - (int ot) const { return x<ot ? x+MOD-ot : x-ot; }
	mint operator * (int ot) const { return 1ll*x*ot%MOD; }
	mint operator += (int ot) { return *this = *this + ot; }
	mint operator -= (int ot) { return *this = *this - ot; }
	mint operator *= (int ot) { return *this = *this * ot; }
	operator int() const { return x; }
};
mint mpow(mint a, int x)
{
	mint ret=1;
	while(x)
	{
		if(x&1) ret*=a;
		a=a*a; x>>=1;
	}
	return ret;
}
mint inv(int a) { return mpow(a, MOD-2); }

const int MAXN = 1000;
const int MAXM = 12;

int N, M, N2;
int A[MAXM+10], B[MAXM+10], C[MAXM+10];
int SA[(1<<MAXM)+10], SC[(1<<MAXM)+10];

mint dp1[MAXN+10][(1<<MAXM)+10], dp2[MAXN+10][(1<<MAXM)+10];

int P[MAXM+10];
mint ans2;
void dfs(int pos, int mask, mint a, mint b)
{
    if(pos==N2+1)
    {
        ans2+=a*b;
        return;
    }
    for(int i=0; i<M; i++)
    {
        if(B[i]==0) continue;
        B[i]--;
        int mask2=mask;
        if(B[i]==0) mask2|=(1<<i);
        printf("PUSH %d / (%d / %d) / (%d / %d)\n", i, C[i]+B[i]+1, N-pos+1-SC[mask], N-pos+1, N-pos+1-SC[mask]);
        dfs(pos+1, mask2, a*inv(N-pos+1-SC[mask])*(C[i]+B[i]+1), b+inv(N-pos+1-SC[mask])*(N-pos+1));
        printf("POP\n");
        B[i]++;
    }
}

mint fac[MAXN+10], ifac[MAXN+10];
mint ncr(int n, int r)
{
    if(0<=r && r<=n) return fac[n]*ifac[r]*ifac[n-r];
    else return 0;
}

int main() {
	cin.tie(0); ios_base::sync_with_stdio(0);

	scanf("%d%d", &N, &M);
	for(int i=0; i<M; i++) scanf("%d", &A[i]);
	for(int i=0; i<M; i++) scanf("%d", &B[i]), N2+=B[i];
	for(int i=0; i<M; i++) C[i]=A[i]-B[i];

    fac[0]=1;
    for(int i=1; i<=N; i++) fac[i]=fac[i-1]*i;
    ifac[N]=inv(fac[N]);
    for(int i=N; i>=1; i--) ifac[i-1]=ifac[i]*i;

	mint p=1;
	for(int i=0; i<M; i++) for(int j=0; j<B[i]; j++) p*=(A[i]-j);

	for(int i=0; i<(1<<M); i++)
	{
		for(int j=0; j<M; j++)
		{
			if(i&(1<<j)) SC[i]+=C[j], SA[i]+=B[j];
		}
	}

	dp1[0][0]=1;
	for(int i=1; i<=N2; i++)
	{
		for(int j=0; j<(1<<M); j++)
		{
			if(SA[j]+1>i) continue;
			if(N2-i+1<M-__builtin_popcount(j)) continue;
			dp1[i][j]=dp1[i-1][j];
			for(int k=0; k<M; k++)
			{
				if(j&(1<<k))
				{
					dp1[i][j]+=dp1[i-1][j^(1<<k)]*ncr(i-2-SA[j^(1<<k)], B[k]-1);
				}
			}
			dp1[i][j]*=inv(N-i+1-SC[j]);
		}
	}
	dp2[N2+1][(1<<M)-1]=1;
	for(int i=N2; i>=1; i--)
	{
		for(int j=0; j<(1<<M); j++)
		{
			if(SA[j]+1>i) continue;
			if(N2-i+1<M-__builtin_popcount(j)) continue;
			dp2[i][j]=dp2[i+1][j];
			for(int k=0; k<M; k++)
			{
				if(!(j&(1<<k)))
				{
					dp2[i][j]+=dp2[i+1][j^(1<<k)]*ncr(i-1-SA[j], B[k]-1);
				}
			}
			dp2[i][j]*=inv(N-i+1-SC[j]);
		}
	}

	mint ans=0;
	for(int i=1; i<=N2; i++)
	{
		for(int j=0; j<(1<<M); j++)
		{
			if(SA[j]+1>i) continue;
			if(N2-i+1<M-__builtin_popcount(j)) continue;
            // printf("%d %d : %d %d\n", i, j, (int)dp1[i][j], (int)dp2[i][j]);
			ans+=mint(N-i+1)*dp1[i][j]*dp2[i][j];
		}
	}
	ans*=p;

    printf("%d\n", (int)ans);
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 36312kb

input:

2 2
1 1
1 1

output:

2

result:

ok answer is '2'

Test #2:

score: 0
Accepted
time: 0ms
memory: 36240kb

input:

4 2
2 2
2 1

output:

582309210

result:

ok answer is '582309210'

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 36308kb

input:

5 5
1 1 1 1 1
0 0 0 0 1

output:

0

result:

wrong answer expected '5', found '0'