ABC419 补题
赛后补的111
A
人机验证题。
#include <bits/stdc++.h>
//#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
inline void print(int x, char ch) {
write(x), putchar(ch);
}
#endif
string s;
signed main() {
cin >> s;
if (s == "red")
cout << "SSS\n";
else if (s == "blue")
cout << "FFF\n";
else if (s == "green")
cout << "MMM\n";
else
cout << "Unknown\n";
return 0;
}
B
小根堆直接做。
#include <bits/stdc++.h>
#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
inline void print(int x, char ch) {
write(x), putchar(ch);
}
#endif
int Q;
priority_queue<int, vector<int>, greater<int>> q;
signed main() {
Q = read();
for (int _ = 1; _ <= Q; _ ++) {
int opt = read(), x;
if (opt == 1) {
x = read();
q.push(x);
}
else
print(q.top(), '\n'), q.pop();
}
return 0;
}
C
首先你发现每个点可以单独考虑,那么取最平均的点即可。
#include <bits/stdc++.h>
#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
inline void print(int x, char ch) {
write(x), putchar(ch);
}
#endif
constexpr int N = 2e5 + 100;
int n, mxx, mxy, mnx, mny;
signed main() {
n = read();
mxx = mxy = -1;
mnx = mny = 1e9 + 7;
for (int i = 1, x, y; i <= n; i ++) {
x = read(), y = read();
mxx = max(mxx, x), mnx = min(mnx, x);
mxy = max(mxy, y), mny = min(mny, y);
}
int ans = max(ceil((mxx - mnx) / 2.0), ceil((mxy - mny) / 2.0));
print(ans, '\n');
return 0;
}
D
你发现只需要考虑每个位置的交换次数的奇偶性即可。
偶则为原来的,奇则为另一个。
#include <bits/stdc++.h>
//#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
inline void print(int x, char ch) {
write(x), putchar(ch);
}
#endif
constexpr int N = 5e5 + 100;
int n, m, d[N];
string s, t;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m >> s >> t;
s = " " + s, t = " " + t;
for (int _ = 1, L, R; _ <= m; _ ++) {
cin >> L >> R;
d[L] ++, d[R + 1] --;
}
for (int i = 1; i <= n; i ++)
d[i] += d[i - 1];
for (int i = 1; i <= n; i ++) {
if (!(d[i] & 1))
cout << s[i];
else
cout << t[i];
}
return 0;
}
E
数据范围很 \(O(n^3)\) 啊,考虑 dp。
你发现如果想直接 dp 需要考虑的状态数较多,考虑找一点性质。
我们最后的情况是 \(sum_{[i,i + L - 1]} \bmod m = 0\),那么就是 \(sum_{[i,i+L-1]} \equiv sum_{[i+1,i+L]} (\bmod \enspace m)\),即可得到 \(a_i \equiv a_{i+L}(\mod \enspace m)\)。
考虑记 \(val_{i,j}\) 表示对于所有模 \(L\) 等于 \(i\) 的下标位置的 \(a_i\) 使得其模 \(m\) 等于 \(j\) 的最小操作次数,则有 \(\forall j = ki(k \geq 0) \land j < n,val_{j,(a_j + k) \bmod m} \leftarrow val_{j,(a_j + k) \bmod m} + k\)。
那么考虑记 \(f_{i,j}\) 表示考虑了前 \(i\) 个和模 \(m\) 为 \(j\) 的最小操作次数。
那么我们只需要考虑前 \(L\) 个就行,因为确定了前 \(L\) 个就确定了整个数组。
则有方程:
答案则为 \(\min\{f_{n,0}\}\)。
#include <bits/stdc++.h>
#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
#endif
constexpr int N = 510;
int n, m, L;
int a[N], val[N][N];
int f[N], g[N];
signed main() {
n = read();
m = read();
L = read();
for (int i = 0; i < n; i ++)
a[i] = read();
for (int i = 0; i < L; i ++) {
for (int j = i; j < n; j += L) {
for (int k = 0; k < m; k ++)
val[i][(a[j] + k) % m] += k;
}
}
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 0; i < L; i ++) {
memset(g, 0x3f, sizeof(g));
for (int j = 0; j < m; j ++) {
for (int k = 0; k < m; k ++)
g[(j + k) % m] = min(g[(j + k) % m], f[j] + val[i][k]);
}
memcpy(f, g, sizeof(f));
}
printf("%lld\n", f[0]);
return 0;
}
F
显然的 ACAM。
但是需要状压 dp。
记 \(f_{i,j,st}\) 表示考虑到了第 \(i\) 位,在 ACAM 上 \(j\) 节点,字符串选择状态 \(st\) 的方案数,最后答案为 \(\sum\limits_{i=0}^{siz}{f_{L,i,U}}\),其中 \(siz\) 为 ACAM 大小,\(U\) 为全集。
那么还需要再字符串末尾记以该节点结尾的总状态,同时在 \(fail\) 链顶记总状态。
转移:\(\forall k \in son_j,f_{i,k,st\mid val_k} \leftarrow f_{i,k,st\mid val_k} + f_{i,j,st}\)。
#include <bits/stdc++.h>
//#define FASTIO
#define int long long
#define son(rt,x) acam[rt].son[x]
#define fail(rt) acam[rt].fail
#define val(rt) acam[rt].val
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
inline void print(int x, char ch) {
write(x), putchar(ch);
}
#endif
constexpr int N = 110;
constexpr int M = (1 << 8) + 5;
constexpr int mod = 998244353;
int n, L, cnt;
string s;
int f[N][N][M];
struct ACAM {
int fail;
int son[26];
int val;
} acam[N];
inline void ins(string str, int id) {
int now = 0;
for (int i = 0; i < (int)str.length(); i ++) {
int chVal = str[i] - 'a';
if (!son(now, chVal))
son(now, chVal) = ++cnt;
now = son(now, chVal);
}
val(now) |= (1 << id);
}
inline void get() {
queue<int> q;
for (int ch = 0; ch < 26; ch ++) {
if (son(0, ch))
q.push(son(0, ch));
}
while (!q.empty()) {
int now = q.front();
q.pop();
val(now) |= val(fail(now));
for (int ch = 0; ch < 26; ch ++) {
if (!son(now, ch))
son(now, ch) = son(fail(now), ch);
else {
fail(son(now, ch)) = son(fail(now), ch);
q.push(son(now, ch));
}
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> L;
for (int i = 0; i < n; i ++)
cin >> s, ins(s, i);
get();
const int U = (1 << n) - 1;
f[0][0][0] = 1;
for (int i = 1; i <= L; i ++) {
for (int now = 0; now <= cnt; now ++) {
for (int st = 0; st <= U; st ++) {
for (int ch = 0; ch < 26; ch ++) {
int j = son(now, ch);
f[i][j][st | val(j)] = (f[i][j][st | val(j)] + f[i - 1][now][st]) % mod;
}
}
}
}
// for (int now = 0; now <= cnt; now ++)
// cout << f[L][now][U] << ' ';
// cout << '\n';
int ans = 0;
for (int now = 0; now <= cnt; now ++)
ans = (ans + f[L][now][U]) % mod;
cout << ans << '\n';
return 0;
}

浙公网安备 33010602011771号