A:Cyclic

模拟

代码实现
a, b, c = input()
print(b+c+a, c+a+b)

B:Strawberries

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    
    int ans = 0;
    rep(i, n-k+1) {
        if (s.substr(i, k) == string(k, 'O')) {
            ans++;
            rep(j, k) s[i+j] = 'X';
        }
    }
    
    cout << ans << '\n';
    
    return 0;
}

C:Sowing Stones

考虑将点 \(p_x\) 处的石子搬到下一个最近的有石子的位置 \(x\) 处,首先这两个位置之间的点都应该放一颗石子,然后留一颗将剩下的石子都搬到位置 \(x\)

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;
using P = pair<int, int>;

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<P> stones(m);
    rep(i, m) cin >> stones[i].first;
    rep(i, m) cin >> stones[i].second;
    
    ranges::sort(stones);
    stones.emplace_back(n+1, 1);
    
    ll ans = 0;
    int px = 0;
    ll num = 1;
    for (auto [x, a] : stones) {
        ll L = x-px;
        ll carry = num-L;
        ans += (L-1)*L/2;
        ans += L*carry;
        if (carry < 0) {
            puts("-1");
            return 0;
        }
        
        px = x;
        num = carry+a;
    }
    
    if (num != 1) puts("-1");
    else cout << ans << '\n';
    
    return 0;
}

D:Home Garden

可以开一个变量 now 来记录到目前为止的 \(\sum T\),然后用队列来模拟即可

代码实现
#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 Q;
    cin >> Q;
    
    queue<ll> q;
    ll now = 0;
    
    rep(Qi, Q) {
        int type;
        cin >> type;
        if (type == 1) q.push(now);
        if (type == 2) {
            ll t;
            cin >> t;
            now += t;
        }
        if (type == 3) {
            ll h;
            cin >> h;
            int ans = 0;
            while (q.size() and now-q.front() >= h) {
                ans++;
                q.pop();
            }
            cout << ans << '\n';
        }
    }
    
    return 0;
}

E:Sum of All Substrings

先将 \(S\) 做一下颠倒,也就是左边变成低位,右边变成高位
d[i] 表示第 \(i\) 位上的贡献,从后往前更新 \(d[i]\) 的值,\(d[n-1] = S_{n-1} \times 1\)\(d[n-2] = S_{n-1} \times 1 + S_{n-2} \times 2\)\(\cdots\)\(d_0 = S_{n-1} \times 1 + S_{n-2} \times 2 + \cdots + S_{0} \times n\)
然后做一下进位操作即可

代码实现
#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;
    string s;
    cin >> n >> s;
    
    ranges::reverse(s);
    
    int mx = n+50;
    vector<ll> d(mx);
    ll sum = 0;
    for (int i = n-1; i >= 0; --i) {
        sum += (s[i]-'0')*(n-i);
        d[i] = sum;
    }
    
    rep(i, mx-1) {
        d[i+1] += d[i]/10;
        d[i] %= 10;
    }
    while (d.back() == 0) d.pop_back();
    
    ranges::reverse(d);
    
    for (int digit : d) cout << digit;
    
    return 0;
}

F: Buildings 2

先维护一个从右往左看单调递减的栈
然后固定 \(r\),找它对应的每个 \(l\),此时栈中大于等于 \([l+1,r]\) 中的最大的 \(h\) 之后的所有数都是 \(l\)\(r\) 可以看到的

代码实现
#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 P = pair<int, int>;

int op(int a, int b) { return max(a, b); }
int e() { return 0; }

int main() {
    int n, q;
    cin >> n >> q;
    
    vector<int> h(n);
    rep(i, n) cin >> h[i];
    
    vector<vector<P>> qs(n);
    rep(i, q) {
        int l, r;
        cin >> l >> r;
        --l; --r;
        qs[r].emplace_back(l, i);
    }
    
    segtree<int, op, e> rmq(h);
    
    vector<int> ans(q);
    vector<int> st;
    for (int i = n-1; i >= 0; --i) {
        for (auto [l, qi] : qs[i]) {
            int max_h = rmq.prod(l+1, i+1);
            int now = lower_bound(st.begin(), st.end(), max_h, greater<int>()) - st.begin();
            ans[qi] = now;
        }
        while (st.size() and st.back() < h[i]) st.pop_back();
        st.push_back(h[i]);
    }
    
    rep(i, q) cout << ans[i] << '\n';
    
    return 0;
}

G: Count Grid 3-coloring

对行做状压dp