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

注意到,\( nnn \cdots n = \overline{1\underbrace{00 \cdots 0}_{m-1}1 \cdots 1 \cdots 1 \underbrace{00 \cdots 0}_{m-1}1 } \times n \),其中 \(m\)\(n\) 的位数

\( \overline{1\underbrace{00 \cdots 0}_{m-1}1 \cdots 1 \cdots 1 \underbrace{00 \cdots 0}_{m-1}1 } = (10^m)^{n-1} + (10^m)^{n-2} + \cdots + (10^m)^0 = \frac{1 - (10^m)^n}{1-10^m} \) (等比数列求和公式)

代码实现
#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

延迟线段树的板题

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

  • \(\sum (A \times B)\)
  • \(\sum B\)
  • \(\sum A\)
  • \(\sum 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;
}