QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#311093 | #7754. Rolling For Days | arnold518 | WA | 0ms | 36312kb | C++17 | 3.4kb | 2024-01-21 21:40:42 | 2024-01-21 21:40:43 |
Judging History
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);
}
Details
Tip: Click on the bar to expand more detailed information
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'