A. 123233

模拟

代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
ranges::sort(s);
if (s == "122333") puts("Yes");
else puts("No");
return 0;
}

B. Hurdle Parsing

模拟

代码实现
print(*map(len, input()[1:-1].split('|')))

C. Move Segment

字符串压缩RLE

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, k;
string s;
cin >> n >> k >> s;
vector<pair<char, int>> rle;
for (char c : s) {
if (rle.size() and rle.back().first == c) rle.back().second++;
else rle.emplace_back(c, 1);
}
int one = 0;
rep(i, rle.size()) {
if (rle[i].first == '1') {
one++;
if (one == k) {
swap(rle[i-1], rle[i]);
}
}
}
string ans;
for (auto [c, len] : rle) {
rep(i, len) ans += c;
}
cout << ans << '\n';
return 0;
}

D. Strange Mirroring

考虑 kn 的二进制表示中 1 的个数的奇偶性,如果是奇数就要修改大小写,否则不需要修改大小写

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
char flip(char c) {
if (islower(c)) return toupper(c);
return tolower(c);
}
int main() {
string s;
cin >> s;
int n = s.size();
int q;
cin >> q;
rep(qi, q) {
ll k;
cin >> k;
--k;
int si = k%n;
k /= n;
int cnt = __builtin_parityll(k);
char ans = s[si];
if (cnt%2) ans = flip(ans);
cout << ans << ' ';
}
return 0;
}

E. 1D Bucket Tool

用并查集来维护同色的块

代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, q;
cin >> n >> q;
vector<int> cnt(n+2, 1);
dsu uf(n+2);
vector<int> l(n+2), r(n+2), col(n+2);
rep(i, n+2) l[i] = r[i] = col[i] = i;
rep(qi, q) {
int type;
cin >> type;
if (type == 1) {
int x, c;
cin >> x >> c;
x = uf.leader(x);
int sz = uf.size(x);
cnt[col[x]] -= sz;
col[x] = c;
cnt[col[x]] += sz;
{
int li = uf.leader(l[x]-1);
if (col[li] == c) {
int nl = l[li], nr = r[x];
uf.merge(li, x);
x = uf.leader(x);
l[x] = nl; r[x] = nr; col[x] = c;
}
}
{
int ri = uf.leader(r[x]+1);
if (col[ri] == c) {
int nl = l[x], nr = r[ri];
uf.merge(ri, x);
x = uf.leader(x);
l[x] = nl; r[x] = nr; col[x] = c;
}
}
}
else {
int c;
cin >> c;
cout << cnt[c] << '\n';
}
}
return 0;
}

F. Exchange Game

记忆化搜索
f(S) 表示从状态 S 开始的胜负

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using S = tuple<vector<int>, vector<int>, vector<int>>;
int main() {
int n, m, l;
cin >> n >> m >> l;
vector<int> a(n), b(m), c(l);
rep(i, n) cin >> a[i];
rep(i, m) cin >> b[i];
rep(i, l) cin >> c[i];
ranges::sort(a);
ranges::sort(b);
ranges::sort(c);
map<S, bool> memo;
auto f = [&](auto& f, S s) {
if (memo.count(s)) return memo[s];
auto [a, b, c] = s;
bool res = false;
rep(i, a.size()) {
auto na = a, nc = c;
nc.push_back(a[i]);
na.erase(na.begin()+i);
ranges::sort(nc);
if (!f(f, S(b, na, nc))) res = true;
rep(j, nc.size()) {
if (nc[j] < a[i]) {
auto na2 = na, nc2 = nc;
nc2.erase(nc2.begin()+j);
na2.push_back(nc[j]);
ranges::sort(na2);
if (!f(f, S(b, na2, nc2))) res = true;
}
}
}
return memo[s] = res;
};
if (f(f, S(a, b, c))) puts("Takahashi");
else puts("Aoki");
return 0;
}

G. Another Shuffle Window

不难看出总方案数为 (nk+1)×k!,下面默认上下都除以 k!
考虑打乱顺序后逆序数会发生什么变化,最后只需看打乱的范围里的逆序数即可
也就是说原序列的逆序数 原序列区间中的逆序数 + 区间中打乱顺序后的逆序数就能得到最终的逆序数
对于第一部分和第三部分是固定的,其中区间中打乱顺序后的逆序数的期望就是 kC22
对于原序列区间中的逆序数,可以用一个队列维护长度为 k 的滑动窗口

代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using mint = modint998244353;
int main() {
int n, k;
cin >> n >> k;
vector<int> p(n);
rep(i, n) cin >> p[i], p[i]--;
ll base = 0;
{
fenwick_tree<int> t(n);
rep(i, n) {
base += t.sum(p[i], n);
t.add(p[i], 1);
}
}
mint ans;
{
fenwick_tree<int> t(n);
ll now = 0;
queue<int> q;
rep(i, n) {
now += t.sum(p[i], n);
t.add(p[i], 1);
q.push(i);
if (q.size() == k) {
ans += now;
int j = q.front(); q.pop();
t.add(p[j], -1);
now -= t.sum(0, p[j]);
}
}
}
ans /= (n-k+1);
ans = mint(base) - ans + mint(k)*(k-1)/2/2;
cout << ans.val() << '\n';
return 0;
}