QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#29304#2576. 麻将ETK100 ✓1008ms10944kbC++143.1kb2022-04-16 22:31:242025-03-11 17:00:22

Judging History

This is the latest submission verdict.

  • [2025-03-11 17:00:22]
  • Judged
  • Verdict: 100
  • Time: 1008ms
  • Memory: 10944kb
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-04-16 22:31:24]
  • Submitted

answer

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define pii pair<int,int>
#define vi vector<int>
#define ll long long
using namespace std;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
const int N=405,M = 2200,P = 998244353,inf = 114514;
int n,cnt[N],fac[N],ifac[N];
int C(int n,int m){return 1ll * fac[n] * ifac[m] % P * ifac[n-m] % P;}
int fpow(int x,int y = P - 2){
    int res = 1;
    while(y){
        if(y & 1)res = 1ll * res * x % P;
        y >>= 1;
        x = 1ll * x * x % P;
    }
    return res;
}
void add(int &x,const ll y){x += y;if(x > P)x -= P;}
void Max(int &x,int y){if(x < y)x = y;}
struct Matrix{
    int f[3][3];
    void clear(){rep(i,0,2)rep(j,0,2)f[i][j] = -1;}
};
Matrix operator + (Matrix A,int x){
    Matrix res;res.clear();
    rep(i,0,2)rep(j,0,2)if(A.f[i][j] != -1){
        rep(k,0,2)if(x >= i + j + k)
            Max(res.f[j][k],min(A.f[i][j] + i + (x-i-j-k) / 3,4));
    }
    return res;
}
void MMax(Matrix &A,Matrix B){
    rep(i,0,2)rep(j,0,2)Max(A.f[i][j],B.f[i][j]);
}
struct node{
    int cnt;
    Matrix dp[2];
    void clear(){cnt = 0;dp[0].clear(),dp[1].clear();}
    bool operator <(const node &u)const{
        rep(t,0,1)rep(i,0,2)rep(j,0,2)
            if(dp[t].f[i][j] ^ u.dp[t].f[i][j])return dp[t].f[i][j] < u.dp[t].f[i][j];
        return cnt < u.cnt;
    }
};
bool Hu(node u){
    if(u.cnt >= 7)return 1;
    rep(i,0,2)rep(j,0,2)if(u.dp[1].f[i][j] >= 4)return 1;
    return 0;
}
node operator + (node u,int x){
    if(u.cnt == inf)return u;
    node res;res.clear();
    res.cnt = u.cnt + (x >= 2);
    rep(t,0,1)MMax(res.dp[t],u.dp[t] + x);
    if(x >= 2)MMax(res.dp[1],u.dp[0] + (x - 2));
    if(Hu(res)){
        res.clear();res.cnt = inf;
    }
    return res;
}
int G[M][5],dp[2][N][M],tot,ans,Winn;
map <node,int> mp;
queue <node> q;
void ins(node u){mp[u] = ++tot,q.push(u);}
void bfs(){
    node s;s.clear();
    s.dp[0].f[0][0] = 0;
    ins(s);
    while(!q.empty()){
        node u = q.front();q.pop();
        int id = mp[u];
        rep(i,0,4){
            node v = u + i;
            if(!mp.count(v)){
                ins(v);
                if(v.cnt == inf)Winn = tot;
            }
            G[id][i] = mp[v];
        }
    }
}
int main(){
    bfs();
    n = read();
    fac[0] = 1;
    rep(i,1,4*n)fac[i] = 1ll * fac[i-1] * i % P;
    ifac[4*n] = fpow(fac[4*n]);
    per(i,4*n,1)ifac[i-1] = 1ll * ifac[i] * i % P;
    rep(i,1,13){
        int x = read(),y = read();
        cnt[x]++;
    }
    dp[0][0][1] = 1;
    rep(i,1,n){
        int now = (i&1);
        memset(dp[now],0,sizeof(dp[now]));
        rep(j,1,tot)rep(k,0,(i-1)*4)rep(c,0,4-cnt[i]){
            add(dp[now][k+c][G[j][c+cnt[i]]],1ll * dp[now^1][k][j] * C(4 - cnt[i],c) % P);
        }
    }
    rep(i,0,4*n-13)rep(j,1,tot)if(j != Winn){
        add(ans,1ll * dp[n & 1][i][j] * fpow(C(4*n-13,i)) % P);
    }
    cout << ans << '\n';
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 10
Accepted
time: 8ms
memory: 10896kb

input:

5
1 1
1 2
1 3
1 4
2 1
3 1
3 2
3 3
3 4
5 1
5 2
5 3
5 4

output:

570425346

result:

ok single line: '570425346'

Test #2:

score: 10
Accepted
time: 7ms
memory: 10900kb

input:

5
1 3
2 4
4 3
5 3
3 1
5 4
4 2
1 4
4 4
3 3
3 2
1 1
2 2

output:

713031682

result:

ok single line: '713031682'

Test #3:

score: 10
Accepted
time: 29ms
memory: 10796kb

input:

13
1 3
12 1
12 2
1 4
13 3
13 2
3 2
13 1
1 1
3 4
3 3
1 2
12 3

output:

868236068

result:

ok single line: '868236068'

Test #4:

score: 10
Accepted
time: 28ms
memory: 10900kb

input:

13
1 1
13 1
2 3
1 3
3 1
3 4
2 1
13 4
1 4
12 2
13 3
12 3
3 2

output:

234399821

result:

ok single line: '234399821'

Test #5:

score: 10
Accepted
time: 29ms
memory: 10896kb

input:

13
2 3
2 1
12 2
13 2
2 2
1 2
13 3
12 4
13 4
3 4
3 1
12 3
1 3

output:

892522858

result:

ok single line: '892522858'

Test #6:

score: 10
Accepted
time: 681ms
memory: 10896kb

input:

81
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1

output:

152635587

result:

ok single line: '152635587'

Test #7:

score: 10
Accepted
time: 899ms
memory: 10760kb

input:

94
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1

output:

339459976

result:

ok single line: '339459976'

Test #8:

score: 10
Accepted
time: 943ms
memory: 10944kb

input:

96
1 2
1 3
1 4
1 1
2 2
2 3
2 4
2 1
3 2
3 3
3 4
3 1
4 2

output:

230028597

result:

ok single line: '230028597'

Test #9:

score: 10
Accepted
time: 720ms
memory: 10816kb

input:

83
1 2
1 3
1 4
1 1
2 2
2 3
2 4
2 1
3 2
3 3
3 4
3 1
4 2

output:

967250236

result:

ok single line: '967250236'

Test #10:

score: 10
Accepted
time: 1008ms
memory: 10940kb

input:

100
67 1
26 4
12 4
11 4
30 4
29 1
1 4
13 3
30 1
64 2
63 1
20 2
32 4

output:

345132636

result:

ok single line: '345132636'

Extra Test:

score: 0
Extra Test Passed