A

按照题意输出即可。

时间复杂度:

空间复杂度:

#include <iostream>

using namespace std;

int n;

void Solve() {
    cin >> n;
    string s(n, 'a');
    cout << s << 'b' << s;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}

B

考虑对长度为 的前缀答案做差。

观察可得答案约等于长度除以三,手玩一下公式前几项防止出错。

时间复杂度:

空间复杂度:

#include <iostream>

using namespace std;

int l;
int r;

void Solve() {
    cin >> l >> r;
    l--;
    for (int i = 2; i > -1; i--) {
        cout << (r + i) / 3 - (l + i) / 3 << ' ';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}

C

不妨令

,马无法跳,答案为

,马只能向左右方向跳,答案为

,中间的格子马无法跳,而剩下八个格子通过一个类似五角星形状的转圈可以全部互相到达,答案为

,可以通过两个 的形状使得所有点都可以互相到达,故答案为 更大时同理,答案为

时间复杂度:

空间复杂度:

#include <iostream>

using namespace std;

using ll = long long;

int n;
int m;

ll Res() {
    if (n > m) {
        swap(n, m);
    }
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return (m + 1) / 2;
    }
    if (m == 3) {
        return 8;
    }
    return (ll)m * n;
}

void Solve() {
    cin >> n >> m;
    cout << Res();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}

D

考虑 的公倍数,所以小数点后长度 位一定是循环节。由于 ,故长度为 符合要求。将 的循环节都不断重复至长度

如果这时 的循环节大于 的循环节,则直接作高精度减法就是答案。否则,做 的高精度减法,然后因为 将所有的位 改为 即可。

时间复杂度:

空间复杂度:

#include <iostream>

using namespace std;

using ll = long long;

int n;
int m;
string a;
string b;

void Solve() {
    cin >> n >> m >> a >> b;
    int k = n * m;
    string res;
    res.reserve(k);
    for (int i = 0; i < m; i++) {
        res += a;
    }
    string resb;
    resb.reserve(k);
    for (int i = 0; i < n; i++) {
        resb += b;
    }
    bool reverse = false;
    if (res < resb) {
        swap(res, resb);
        reverse = true;
    }
    for (int i = k - 1; i > -1; i--) {
        res[i] -= resb[i] - '0';
        if (res[i] < '0') {
            res[i] += 10;
            res[i - 1]--;
        }
    }
    if (reverse) {
        for (auto& c : res) {
            c = 9 - (c - '0') + '0';
        }
    }
    cout << k << '\n' << res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}

E

发现题目描述等价于对每一个子树求最深非叶子节点的数量。考虑 DP。

记录最深非叶子节点的深度以及数量,搜索时不断合并自身和新子树的信息。合并时,如果深度不同保留更深的深度和数量,否则将数量求和,深度不变。

时间复杂度:

空间复杂度:

#include <iostream>
#include <vector>

using namespace std;

using ll = long long;

using pii = pair<int, int>;

int n;

vector<vector<int>> graph;

vector<pii> res;

void Dfs(int x, int fa, int h) {
    bool leaf = true;
    int maxh = 0;
    int sz = 0;
    for (const auto& y : graph[x]) {
        if (y != fa) {
            if (leaf) {
                leaf = false;
                if (h > maxh) {
                    maxh = h;
                    sz = 1;
                }
                else if (h == maxh) {
                    sz++;
                }
            }
            Dfs(y, x, h + 1);
            auto [yh, ysz] = res[y];
            if (yh > maxh) {
                maxh = yh;
                sz = ysz;
            }
            else if (yh == maxh) {
                sz += ysz;
            }
        }
    }
    res[x] = {maxh, sz};
}

void Solve() {
    cin >> n;
    graph.resize(n + 1);
    res.resize(n + 1);
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    Dfs(1, 0, 0);
    for (int i = 1; i <= n; i++) {
        cout << res[i].second << ' ';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}

F

考虑前缀做差,设长度为 的前缀为 。答案为

考虑将长度为 的前缀分为两部分:长度为 的前半部分以及长度为 的后半部分。后半部分直接暴力求解。前半部分等于 。这个式子可以用等比数列求和公式快速求出。

使用快速幂来计算这些式子,注意随时取模。

时间复杂度:

空间复杂度:

#include <iostream>
#include <vector>

using namespace std;

using ll = long long;

using pii = pair<int, int>;

const int MOD = 998244353;

ll Pow(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b &1) {
            res=res*a %MOD;
        }
        a=a*a%MOD;
        b>>=1;
    }
    return res;
}

ll Inv(ll a) {
    return Pow(a, MOD - 2);
}

int n;
ll l;
ll r;

string x;
ll valx;

ll base;
// 10**

ll Pre(ll r) {
    ll t = r / n;
    int yu = r % n;
    ll val = 0;
    for (int i = 0; i < yu; i++) {
        val = (val * 10 + (x[i] - '0')) % MOD;
    }
    if (base == 1) {
        val = (val + valx * t % MOD * Pow(10, yu)) % MOD;
    }
    else {
        val = (val + (Pow(base, t) - 1) * Inv(base - 1) % MOD * valx % MOD * Pow(10, yu)) % MOD;
    }
    return val;
}

void Solve() {
    cin >> n >> l >> r >> x;
    valx = 0;
    for (const auto& c : x) {
        valx = (valx * 10 + (c - '0')) % MOD;
    }
    base = Pow(10, n);
    ll res = (Pre(r) - Pre(l - 1) * Pow(10, r - l + 1)) % MOD;
    if (res < 0) {
        res += MOD;
    }
    cout << res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Solve();
    return 0;
}