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);
}
}

浙公网安备 33010602011771号