2024 ICPC Asia Chengdu Regional Contest (The 3rd Universal Cup. Stage 15: Chengdu) - B

补题链接
\(对于该题 我们首先朴素地思考\)
\(对其前三维 a,b,c的个数十分的少\)
\(我们考虑对每一位进行填充\)
\(但是这时我们需要考虑到这一位填什么和该位是第几位 还有a,b,c已经填充的个数\)
\(空间复杂度为300*300*300*300*3>1e8\)
\(很明显不符合题目要求\)
\(考虑优化\)
\(将?提取出来\)
\(对于其前面的每一位进行枚举思考\)
\(进行分类讨论\)
\(step1:如果前面为a,b,c中的一种那么将其打上标记(不能进行填充) 如果前面的一位为?那么通过?对前面一位进行讨论\)
\(step2:接下来讨论右边 如果右边为a,b,c中的一位 同样将其打上标记 反之 如果为?那么不需要标记直接进行状态转移即可\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define rep(a,b,c) for(int a=b; a<=c; a++)
#define YES cout << "Yes\n" 
#define NO cout << "No\n" 
#define ar2 array<int,2>
#define all(x) x.begin() + 1, x.end()
int dx[] = { 0,1,-1,0,0,1,1,-1,1 };
int dy[] = { 0,0,0,1,-1,1,-1,1,1 };
typedef long long ll;
typedef unsigned long long ull;
//---------------------------//
#ifdef LOCAL
template <class... Args> void debug(const Args&... args) { ((cerr << args << ", "), ...) << '\n'; }
#define debug(args...) cerr << #args << ": ", debug(args)
#define debugsq(x) cerr << #x << ": ["; for (auto i : x) cerr << i << ' '; cerr << "]\n";
#define debugmp(x) cerr << #x << ": [ "; for (auto [i, j] : x) cerr << '[' << i << "," << j << "] "; cerr << "]\n";
#else
#define debug(...) ;
#define debugsq(...) ;
#define debugmp(...) ;
#endif
//---------------------------//

int dp[305][305][305][3];
int sum[305][305][305];
const int mod = 1e9 + 7;
int norm(int x) {
    return (x % mod + mod) % mod;
}
void solve(int TIME) {
    int n, q; cin >> n >> q;
    string s; cin >> s;
    s = " " + s + " ";
    vector<int>tmp(n + 1);
    int cnt = 0;
    vector<int>pos;
    dp[0][0][0][0]=1;
    for (int i = 1; i <= n; i++) {
        if (s[i] == '?')tmp[i] = 0, cnt++, pos.push_back(i);
        else tmp[i] = s[i] - 'a' + 1;
    }


    for (int a = 0; a <= cnt; a++) {
        for (int b = 0; b <= cnt; b++) {
            for (int c = 0; c <= cnt; c++) {

                if (a + b + c > cnt)break;
                if (a + b + c == 0)continue;

                int now_pos = pos[a + b + c - 1];
                int l = now_pos - 1, r = now_pos + 1;
                if (s[l] == '?') {
                    vector<int>vis(3,0);
                    if (s[r] != '?'&&s[r]!=' ')vis[s[r] - 'a'] = 1;
                    for (int col = 0; col < 3; col++) {
                        if (vis[col])continue;
                        for (int k = 1; k <= 2; k++) {
                            int nowa = a, nowb = b, nowc = c;
                            if (col == 0)nowa--;
                            else if (col == 1)nowb--;
                            else nowc--;
                            if (nowa == -1 || nowb == -1 || nowc == -1)break;
                            dp[a][b][c][col] = (dp[a][b][c][col] + dp[nowa][nowb][nowc][(col + k) % 3]) % mod;
                        }
                    }
                }
                else {
                    vector<int>vis(3);
                    
                    if(s[l]!=' ')vis[s[l] - 'a'] = 1;
                    if (s[r] != '?'&&s[r]!=' ')vis[s[r] - 'a'] = 1;
                    for (int col = 0; col < 3; col++) {
                        if (vis[col])continue;
                        for (int k = 0; k <= 2; k++) {
                            int nowa = a, nowb = b, nowc = c;
                            if (col == 0)nowa--;
                            else if (col == 1)nowb--;
                            else nowc--;
                            if (nowa == -1 || nowb == -1 || nowc == -1)break;
                            dp[a][b][c][col] = (dp[a][b][c][col] + dp[nowa][nowb][nowc][(col + k) % 3]) % mod;
                        }
                    }
                }
            }
        }
    }
    
    for (int a = 0; a <= cnt; a++) {
        for (int b = 0; b <= cnt - a; b++) {
            int c = cnt - a - b;
            for (int k = 0; k < 3; k++) {
                sum[a][b][c] = (sum[a][b][c] + dp[a][b][c][k]) % mod;
                // debug(a, b, c, k);
                // debug(sum[a][b][c]);
                // cerr << endl;
                // debug()
            }
        }
    }
    
    for (int i = 0; i <=300; i++) {
        for (int j = 0; j <=300; j++) {
            for (int k = 0; k <=300; k++) {
                if (i > 0) sum[i][j][k] += sum[i - 1][j][k]; sum[i][j][k] %= mod;
                if (j > 0) sum[i][j][k] += sum[i][j - 1][k]; sum[i][j][k] %= mod;
                if (k > 0) sum[i][j][k] += sum[i][j][k - 1]; sum[i][j][k] %= mod;
                if(i&&j)sum[i][j][k]+=mod-sum[i-1][j-1][k];sum[i][j][k] %= mod;
                if(k&&j)sum[i][j][k]+=mod-sum[i][j-1][k-1];sum[i][j][k] %= mod;
                if(i&&k)sum[i][j][k]+=mod-sum[i-1][j][k-1];sum[i][j][k] %= mod;
                if(i&&j&&k)sum[i][j][k]+=sum[i-1][j-1][k-1];sum[i][j][k] %= mod;
            }
        }
    }
    
    while (q--) {
        int x, y, z; cin >> x >> y >> z;
        cout << sum[x][y][z] << '\n';
    }
}
signed main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int _ = 1;
    // cin >> _;
    for (int TIME = 1; TIME <= _; TIME++) {
        solve(TIME);
    }
}
posted @ 2024-11-06 19:03  archer2333  阅读(160)  评论(0)    收藏  举报