A. Sanitize Hands

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> h(n);
rep(i, n) cin >> h[i];
int ans = 0;
rep(i, n) {
if (m < h[i]) break;
m -= h[i];
ans++;
}
cout << ans << '\n';
return 0;
}

B. Uppercase and Lowercase

模拟

代码实现
s = input()
l = sum(map(str.islower, s))
u = len(s) - l
if u > l: s = s.upper()
else: s = s.lower()
print(s)

也可以用C++的 std::transform 函数

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
string s;
cin >> s;
int l = 0, u = 0;
for (char c : s) {
if (islower(c)) l++;
else u++;
}
if (u > l) {
transform(s.begin(), s.end(), s.begin(), [](char c) { return toupper(c); });
}
else {
transform(s.begin(), s.end(), s.begin(), [](char c) { return tolower(c); });
}
cout << s << '\n';
return 0;
}

C. Sierpinski carpet

递归或递推

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<string> s = {"#"};
rep(ni, n) {
int m = s.size(), m3 = m*3;
vector<string> t(m3, string(m3, '.'));
rep(i, m3)rep(j, m3) t[i][j] = s[i%m][j%m];
rep(i, m)rep(j, m) t[m+i][m+j] = '.';
swap(s, t);
}
rep(i, s.size()) cout << s[i] << '\n';
return 0;
}

D. 88888888

注意到,nnnn=1000m1111000m11¯×n,其中 mn 的位数

1000m1111000m11¯=(10m)n1+(10m)n2++(10m)0=1(10m)n110m (等比数列求和公式)

代码实现
#include <bits/stdc++.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using mint = modint998244353;
int main() {
ll n;
cin >> n;
mint a = 1;
{
ll _n = n;
while (_n) {
a *= 10;
_n /= 10;
}
}
mint s = (a.pow(n)-1)/(a-1);
s *= n;
cout << s.val() << '\n';
return 0;
}

E. Reachability in Functional Graph

基环树森林
可以先找到每个基环树上的环,然后从环上的点出发向树边方向递推即可

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
rep(i, n) a[i]--;
vector<bool> used(n);
vector<int> idx(n, -1);
vector<int> ord;
vector<int> cnt(n);
rep(sv, n) if (!used[sv]) {
int v = sv;
vector<int> vs;
while (1) {
if (used[v]) break;
if (idx[v] != -1) {
vector<int> cyc(vs.begin()+idx[v], vs.end());
for (int u : cyc) cnt[u] = cyc.size();
break;
}
idx[v] = vs.size();
vs.push_back(v);
v = a[v];
}
for (int v : vs) used[v] = true;
reverse(vs.begin(), vs.end());
ord.insert(ord.end(), vs.begin(), vs.end());
}
for (int v : ord) {
if (cnt[v] != 0) continue;
cnt[v] = cnt[a[v]]+1;
}
ll ans = 0;
rep(i, n) ans += cnt[i];
cout << ans << '\n';
return 0;
}

F. Two Sequence Queries

延迟线段树的板题

每个点需要维护以下信息:

  • (A×B)
  • B
  • A
  • 1 (也就是区间大小)
代码实现
#include <bits/stdc++.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using mint = modint998244353;
struct S {
mint ab, a, b, w;
S(mint ab=0, mint a=0, mint b=0, mint w=0): ab(ab), a(a), b(b), w(w) {}
};
S op(S x, S y) {
return S(x.ab+y.ab, x.a+y.a, x.b+y.b, x.w+y.w);
}
S e() { return S(); }
struct F {
mint a, b;
F(mint a=0, mint b=0): a(a), b(b) {}
};
S mapping(F f, S x) {
x.ab += f.a*x.b + x.a*f.b + f.a*f.b*x.w;
x.a += f.a * x.w;
x.b += f.b * x.w;
return x;
}
F composition(F g, F f) {
return F(f.a+g.a, f.b+g.b);
}
F id() { return F(); }
int main() {
int n, q;
cin >> n >> q;
vector<int> a(n), b(n);
rep(i, n) cin >> a[i];
rep(i, n) cin >> b[i];
lazy_segtree<S, op, e, F, mapping, composition, id> t(n);
rep(i, n) t.set(i, S(mint(a[i])*b[i], a[i], b[i], 1));
rep(qi, q) {
int type, l, r;
cin >> type >> l >> r;
--l;
if (type == 3) {
S s = t.prod(l, r);
cout << s.ab.val() << '\n';
}
else {
int x;
cin >> x;
if (type == 1) t.apply(l, r, F(x, 0));
else t.apply(l, r, F(0, x));
}
}
return 0;
}