QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#94929#5576. Advertising ICPCNicolas125841TL 2ms4444kbC++143.9kb2023-04-08 12:52:552023-04-08 12:52:57

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-08 12:52:57]
  • 评测
  • 测评结果:TL
  • 用时:2ms
  • 内存:4444kb
  • [2023-04-08 12:52:55]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll mod = 98244353;

ll euclid(ll a, ll b, ll &x, ll &y) {
    if (!b) return x = 1, y = 0, a;

    ll d = euclid(b, a % b, y, x);

    return y -= a/b * x, d;
}

struct Mod {
    ll x;

    Mod() { x = 0; }

    Mod(ll xx) : x(xx) {}

    Mod operator+(Mod b) { return Mod((x + b.x) % mod); }

    Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }

    Mod operator*(Mod b) { return Mod((x * b.x) % mod); }

    Mod operator/(Mod b) { return *this * invert(b); }

    Mod invert(Mod a) {
        ll x, y, g = euclid(a.x, mod, x, y);
        assert(g == 1); return Mod((x + mod) % mod);
    }

    Mod operator^(ll e) {
        if (!e) return Mod(1);

        Mod r = *this ^ (e / 2); r = r * r;

        return e&1 ? *this * r : r;
    }
};

Mod dp[8][6561][2];
int mp[8][8], j_vals[8];
unordered_set<int> matches;

int conv(char c){
    if(c == 'C')
        return 0;
    else if(c == 'I')
        return 1;
    else if(c == 'P')
        return 2;
    else
        return -1;
}

int main(){
    cin.tie(NULL)->sync_with_stdio(false);

    int n, m;
    char tmp;

    cin >> n >> m;

    int m_max = pow(3, m);

    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> tmp;

            mp[i][j] = conv(tmp);
        }
    }

    for(int j = 0; j < m_max; j++){
        bool good = true;
        int tj = j;

        for(int l = 0; l < m; l++){
            j_vals[l] = tj%3;

            if(mp[0][l] != -1 && mp[0][l] != j_vals[l])
                good = false;

            tj /= 3;
        }

        if(good)
            dp[0][j][0] = 1;
        else
            dp[0][j][0] = 0;
        
        dp[0][j][1] = 0;
    }
    
    for(int i = 1; i < n; i++){
        vector<vector<int>> adds(7, vector<int>());
        Mod sum0 = 0, sum1 = 0;

        for(int j = 0; j < m_max; j++){
            bool good = true;
            int tj = j;

            sum0 = sum0 + dp[i-1][j][0];
            sum1 = sum1 + dp[i-1][j][1];

            for(int l = 0; l < m; l++){
                j_vals[l] = tj%3;

                if(mp[i-1][l] != -1 && mp[i-1][l] != j_vals[l])
                    good = false;
                                
                tj /= 3;
            }

            if(good){
                for(int l = 0; l < m-1; l++){
                    if(j_vals[l] == 1 && j_vals[l+1] == 0)
                        adds[l].push_back(j);
                }                
            }
        }

        for(int j = 0; j < m_max; j++){
            bool good = true;
            int tj = j;

            for(int l = 0; l < m; l++){
                j_vals[l] = tj%3;

                if(mp[i][l] != -1 && mp[i][l] != j_vals[l])
                    good = false;
                                
                tj /= 3;
            }

            matches.clear();
            dp[i][j][0] = dp[i][j][1] = 0;

            if(good){
                for(int l = 0; l < m-1; l++){
                    if(j_vals[l] == 2 && j_vals[l+1] == 0){
                        for(int v : adds[l]){
                            matches.insert(v);
                        }
                    }
                }  

                Mod tsum0 = sum0;
                Mod tsum1 = sum1;

                for(int v : matches){
                    tsum0 = tsum0 - dp[i-1][v][0];
                    tsum1 = tsum1 - dp[i-1][v][1];
                    dp[i][j][1] = dp[i][j][1] + dp[i-1][v][0] + dp[i-1][v][1];
                }   

                dp[i][j][0] = dp[i][j][0] + tsum0;
                dp[i][j][1] = dp[i][j][1] +  tsum1;           
            }
        }
    }

    Mod ans = 0;
    
    for(int i = 0; i < m_max; i++){
        ans = ans + dp[n-1][i][1];
    }

    cout << ans.x << "\n";
}

//????????

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 4292kb

input:

3 3
???
?I?
???

output:

243

result:

ok single line: '243'

Test #2:

score: 0
Accepted
time: 2ms
memory: 4444kb

input:

2 2
IC
PC

output:

1

result:

ok single line: '1'

Test #3:

score: -100
Time Limit Exceeded

input:

8 8
????????
????????
????????
????????
????????
????????
????????
????????

output:


result: