「游记」The 2023 ICPC Asia Regionals Online Contest (1)

发布时间 2023-09-18 09:01:55作者: yu__xuan

N/A

考试一开始在找签到题(脑子有病吧

最后还是跟着榜做的题。

队友看了 \(L,D\),我看了 \(A\),写完 \(D\) 机房断网了,看别人知道了必须要重启电脑(此时距断网已经过了二十分钟左右了),重启电脑后交了 \(D\) 此时还是校内三题队第一,校内排名也还不错。

继续跟榜做,写 \(D\) 的时候队友开了 \(J\),我就去看了 \(I\),写了三道题的代码名次还不错有点懈怠了没秒了 \(I\) 是我的错。写完 \(I\) 有各种各样 \(bug\) 就虚拟打印出来去找 \(bug\) 让队友写 \(J\) 了。找到了 \(I\) 的问题等队友写完 \(J\) 我上去改的时候忘改了一处,然后一整场没调出来,队友 \(J\) 也没调出来,怎么绘世鸭。

最后获得了校倒数第一的好成绩,成功被 \(23\) 级吊打。

题解

I

简单 \(dp\)\(f[i][j][0/1][0/1][0/1]\) 表示前 \(i\) 位密码且第 \(i\) 位字符为 \(j\),是否(\(0/1\))满足出现过大写字母,是否(\(0/1\))满足出现过小写字母,是否(\(0/1\))满足出现过数字,有多少种合法情况。空间只给了 \(32MB\),使用滚动数组就行了。转移就是分类讨论。

考场上没想到把后三维用状压压成一维,想到的话这题会不会就调出来了呢。

#include <bits/stdc++.h>

int n;
std::string s;
int cti[518], itc[101];
const int mod = 998244353;
long long in[2][2][2], ex[518][2][2][2], f[2][101][2][2][2];

int main() {
	scanf("%d", &n);
	std::cin >> s;
	int cnt = 0;
	for (int i = '0'; i <= '9'; ++i) cti[i] = cnt, itc[cnt++] = i;
	for (int i = 'a'; i <= 'z'; ++i) cti[i] = cnt, itc[cnt++] = i;
	for (int i = 'A'; i <= 'Z'; ++i) cti[i] = cnt, itc[cnt++] = i;
	int now = 0;
	if ((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= '0' && s[0] <= '9')) {
		if (s[0] >= 'A' && s[0] <= 'Z') f[0][cti[s[0]]][1][0][0] = 1;
		else f[0][cti[s[0]]][0][0][1] = 1;
	} else if (s[0] >= 'a' && s[0] <= 'z') {
		f[0][cti[s[0]]][0][1][0] = 1;
		f[0][cti[s[0]] + 26][1][0][0] = 1;
	} else {
		for (int i = 0; i < cnt; ++i) {
		  if (itc[i] >= '0' && itc[i] <= '9') f[0][i][0][0][1] = 1;
			else if (itc[i] >= 'a' && itc[i] <= 'z') f[0][i][0][1][0] = 1;
			else f[0][i][1][0][0] = 1;
		}
	}
	for (int j = 1; j < n; ++j) {
		in[0][0][0] = 0;
		in[0][0][1] = 0;
		in[0][1][0] = 0;
		in[0][1][1] = 0;
		in[1][0][0] = 0;
		in[1][0][1] = 0;
		in[1][1][0] = 0;
		in[1][1][1] = 0;
		for (int i = 0; i <= cnt; ++i) {
			in[0][0][0] = (in[0][0][0] + f[now][i][0][0][0]) % mod;
			in[0][0][1] = (in[0][0][1] + f[now][i][0][0][1]) % mod;
			in[0][1][0] = (in[0][1][0] + f[now][i][0][1][0]) % mod;
			in[0][1][1] = (in[0][1][1] + f[now][i][0][1][1]) % mod;
			in[1][0][0] = (in[1][0][0] + f[now][i][1][0][0]) % mod;
			in[1][0][1] = (in[1][0][1] + f[now][i][1][0][1]) % mod;
			in[1][1][0] = (in[1][1][0] + f[now][i][1][1][0]) % mod;
			in[1][1][1] = (in[1][1][1] + f[now][i][1][1][1]) % mod;
		}
		for (int i = 0; i < cnt; ++i) {
			ex[i][0][0][0] = (in[0][0][0] - f[now][i][0][0][0] + 2 * mod) % mod;
			ex[i][0][0][1] = (in[0][0][1] - f[now][i][0][0][1] + 2 * mod) % mod;
			ex[i][0][1][0] = (in[0][1][0] - f[now][i][0][1][0] + 2 * mod) % mod;
			ex[i][0][1][1] = (in[0][1][1] - f[now][i][0][1][1] + 2 * mod) % mod;
			ex[i][1][0][0] = (in[1][0][0] - f[now][i][1][0][0] + 2 * mod) % mod;
			ex[i][1][0][1] = (in[1][0][1] - f[now][i][1][0][1] + 2 * mod) % mod;
			ex[i][1][1][0] = (in[1][1][0] - f[now][i][1][1][0] + 2 * mod) % mod;
			ex[i][1][1][1] = (in[1][1][1] - f[now][i][1][1][1] + 2 * mod) % mod;
		}
		now ^= 1;
		for (int i = 0; i < cnt; ++i) {
		  f[now][i][0][0][0] = 0, f[now][i][0][0][1] = 0, f[now][i][0][1][0] = 0, f[now][i][0][1][1] = 0;
			f[now][i][1][0][0] = 0, f[now][i][1][0][1] = 0, f[now][i][1][1][0] = 0, f[now][i][1][1][1] = 0;
		}
		if ((s[j] >= 'A' && s[j] <= 'Z') || (s[j] >= '0' && s[j] <= '9')) {
			if (s[j] >= 'A' && s[j] <= 'Z') {
				for (int i = 0; i < cnt; ++i) {
					if (itc[i] == s[j]) continue;
					if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][1][0][0] += f[now ^ 1][i][0][0][0]) %= mod;
					if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
					if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
					if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
					if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][0][0] += f[now ^ 1][i][1][0][0]) %= mod;
					if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
					if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
					if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
				}
			} else {
				for (int i = 0; i < cnt; ++i) {
					if (itc[i] == s[j]) continue;
					if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][0][0][1] += f[now ^ 1][i][0][0][0]) %= mod;
					if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][0][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
					if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][0]) %= mod;
					if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
					if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][0]) %= mod;
					if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
					if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][0]) %= mod;
					if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
				}
			}
		} else if (s[j] >= 'a' && s[j] <= 'z') {
			for (int i = 0; i < cnt; ++i) {
				if (itc[i] != s[j]) {
					if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][0][1][0] += f[now ^ 1][i][0][0][0]) %= mod;
					if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][0][1]) %= mod;
					if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][0][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
					if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
					if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][0][0]) %= mod;
					if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][0][1]) %= mod;
					if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
					if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
				}
				if (itc[i] != s[j] - 'a' + 'A') {
					if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j] - 'a' + 'A']][1][0][0] += f[now ^ 1][i][0][0][0]) %= mod;
					if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j] - 'a' + 'A']][1][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
					if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j] - 'a' + 'A']][1][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
					if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j] - 'a' + 'A']][1][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
					if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j] - 'a' + 'A']][1][0][0] += f[now ^ 1][i][1][0][0]) %= mod;
					if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j] - 'a' + 'A']][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
					if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j] - 'a' + 'A']][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
					if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j] - 'a' + 'A']][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
				}
			}
		} else {
			for (int i = 0; i < cnt; ++i) {
				if(itc[i] >= 'A' && itc[i] <= 'Z') {
					f[now][i][1][0][0] = (ex[i][1][0][0] + ex[i][0][0][0]) % mod;
					f[now][i][1][0][1] = (ex[i][1][0][1] + ex[i][0][0][1]) % mod;
					f[now][i][1][1][0] = (ex[i][1][1][0] + ex[i][0][1][0]) % mod;
					f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][0][1][1]) % mod;
				} else if (itc[i] >= 'a' && itc[i] <= 'z'){
					f[now][i][0][1][0] = (ex[i][0][1][0] + ex[i][0][0][0]) % mod;
					f[now][i][0][1][1] = (ex[i][0][1][1] + ex[i][0][0][1]) % mod;
					f[now][i][1][1][0] = (ex[i][1][1][0] + ex[i][1][0][0]) % mod;
					f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][1][0][1]) % mod;
				} else {
					f[now][i][0][0][1] = (ex[i][0][0][1] + ex[i][0][0][0]) % mod;
					f[now][i][0][1][1] = (ex[i][0][1][1] + ex[i][0][1][0]) % mod;
					f[now][i][1][0][1] = (ex[i][1][0][1] + ex[i][1][0][0]) % mod;
					f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][1][1][0]) % mod;
				}
			}
		}
	}
	if ((s[n - 1] >= 'A' && s[n - 1] <= 'Z') || (s[n - 1] >= '0' && s[n - 1] <= '9')) {
		std::cout << f[now][cti[s[n - 1]]][1][1][1] % mod << '\n';
	} else if (s[n - 1] >= 'a' && s[n - 1] <= 'z') {
		std::cout << (f[now][cti[s[n - 1]]][1][1][1] + f[now][cti[s[n - 1] - 'a' + 'A']][1][1][1]) % mod << '\n';
	} else {
		long long ans = 0;
		for (int i = 0; i < cnt; ++i) ans = (ans + f[now][i][1][1][1]) % mod;
		std::cout << ans << '\n';
	}
	return 0;
}