2023年码蹄杯决赛题解(三)

目录

MC0253 凡家物语

MC0241 防火墙

MC0254 组合游戏

MC0244 多重堡垒

MC0250 循环

MC0253 凡家物语

#include <bits/stdc++.h>

using namespace std;
#define int long long

struct MyTree {
    unordered_map<int, int[26]> tree;
    int cnt{};
    unordered_map<int, int> end;
    unordered_map<int, int> sum;

    void insert(const string&s, int v) {
        int p = 0;
        int n = (int) s.size();
        for (int i = 0; i < n; i++) {
            int it = s[i] - 'a';
            if (!tree[p][it]) {
                tree[p][it] = ++cnt;
            }
            p = tree[p][it];
        }
        end[p]++;
        sum[p] += v;
    }

    int find(const string&s) {
        int p = 0;
        int n = (int) s.size();
        for (int i = 0; i < n; i++) {
            int it = s[i] - 'a';
            if (!tree[p][it]) {
                return 0;
            }
            p = tree[p][it];
        }
        return p;
    }

    void update(int x, int v) {
        if (end.find(x) != end.end()) {
            sum[x] += v * end[x];
        }
        for (int i = 0; i < 26; i++) {
            if (!tree[x][i]) {
                continue;
            }
            update(tree[x][i], v);
        }
    }

    int search(int x) {
        int ans = 0;
        if (sum.find(x) != sum.end()) {
            ans += sum[x];
        }
        for (int i = 0; i < 26; i++) {
            if (!tree[x][i]) {
                continue;
            }
            ans += search(tree[x][i]);
        }
        return ans;
    }

    void update(const string&s, int v) {
        int x = find(s);
        if (x == 0) {
            return;
        }
        update(x, v);
    }

    int search(const string&s) {
        int x = find(s);
        if (x == 0) {
            return 0;
        }
        return sum[x];
    }

    int searchAll(const string&s) {
        int x = find(s);
        if (x == 0) {
            return 0;
        }
        return search(x);
    }
};

void solve() {
    int n;
    cin >> n;
    MyTree tree;
    ostringstream oss;
    for (int i = 0; i < n; i++) {
        int op;
        cin >> op;
        string s;
        int v;
        if (op == 1) {
            cin >> s >> v;
            tree.insert(s, v);
        } else if (op == 2) {
            cin >> s >> v;
            tree.update(s, v);
        } else if (op == 3) {
            cin >> s;
            oss << tree.search(s) << '\n';
        } else if (op == 4) {
            cin >> s;
            oss << tree.searchAll(s) << '\n';
        }
    }
    cout << oss.str();
}

auto main() -> signed {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    solve();
    return 0;
}

MC0241 防火墙

def find(it: str) -> int:
    k = 0
    i = 0
    j = 0
    n = len(it)
    while k < n and i < n and j < n:
        if i == j:
            j += 1
        if it[(i + k) % n] == it[(j + k) % n]:
            k += 1
            continue
        if it[(i + k) % n] > it[(j + k) % n]:
            i += k + 1
        else:
            j += k + 1
        k = 0
    return min(i, j)


def solve():
    A = input()
    B = input()
    if len(A) != len(B) or B not in 2 * A:
        print("No")
        return
    a = find(A)
    A = A[a:] + A[:a]
    print("Yes")
    print(A)


if __name__ == "__main__":
    solve()

MC0254 组合游戏

#include <bits/stdc++.h>

using namespace std;
#define int long long

int n, k, L, R;
vector<int> sum;
vector<vector<int>> F;

void createST() {
    for (int i = 1; i <= n; i++) {
        F[i][0] = i;
    }
    int k = (int) log2(n);
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j + (1 << i) - 1 <= n; j++) {
            int x = F[j][i - 1];
            int y = F[j + (1 << i - 1)][i - 1];
            F[j][i] = sum[x] > sum[y] ? x : y;
        }
    }
}

int queryST(int l, int r) {
    int k = (int) log2(r - l + 1);
    int x = F[l][k];
    int y = F[r - (1 << k) + 1][k];
    return sum[x] > sum[y] ? x : y;
}

struct node {
    int start{};
    int l{};
    int r{};
    int maxIndex{};

    node() = default;

    node(long long start, long long l, long long r)
        : start(start), l(l), r(r) {
        maxIndex = queryST(l, r);
    }

    [[nodiscard]] int get() const {
        return sum[maxIndex] - sum[start - 1];
    }

    bool operator<(const node&other) const {
        return get() < other.get();
    }
};

void solve() {
    cin >> n >> k >> L >> R;
    sum.assign(n + 1, 0);
    F.assign(n + 1, vector<int>((int) log2(n) + 1, 0));
    for (int i = 1; i <= n; i++) {
        cin >> sum[i];
        sum[i] += sum[i - 1];
    }
    createST();
    priority_queue<node> queue;
    for (int i = 1; i <= n; i++) {
        if (i + L - 1 <= n) {
            queue.emplace(i, i + L - 1, min(i + R - 1, n));
        }
    }
    int ans = 0;
    for (int i = 0; i < k; i++) {
        node it = queue.top();
        queue.pop();
        ans += it.get();
        if (it.maxIndex > it.l) {
            queue.emplace(it.start, it.l, it.maxIndex - 1);
        }
        if (it.maxIndex < it.r) {
            queue.emplace(it.start, it.maxIndex + 1, it.r);
        }
    }
    cout << ans << endl;
}

auto main() -> signed {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    solve();
    return 0;
}

MC0244 多重堡垒

def getLeft(i: int) -> int:
    return i * 2 + 1


def getRight(i: int) -> int:
    return i * 2 + 2


def dfs(i: int, deep: int):
    global ms
    if i >= n:
        return
    ms = max(ms, tree[i] * deep)
    dfs(getLeft(i), deep + 1)
    dfs(getRight(i), deep + 1)


def find(i: int):
    global res, ms
    ms = 0
    dfs(i, 0)
    res += ms


def solve():
    global n, tree, ms, res

    ms = 0
    res = 0
    n = int(input())
    tree = list(map(int, input().split()))
    for i in range(n):
        find(i)
    print(res)


if __name__ == '__main__':
    solve()

MC0250 循环

#include <bits/stdc++.h>

using namespace std;

int k;

class BigInteger {
public:
    string data;
    bool sign; // 符号:true 表示为正数,false 表示为负数
    BigInteger() {
        data = "0";
        sign = true;
        clear();
    }

    // 构造函数
    explicit BigInteger(string s) {
        int i = 0;
        while (s[i] == '-') {
            i++;
        }
        if (i % 2 == 0) {
            sign = true;
        } else {
            sign = false;
        }
        s = s.substr(i);
        data = s;
        clear();
    }

    // 构造函数
    explicit BigInteger(int n) {
        string s = to_string(n);
        int i = 0;
        while (s[i] == '-') {
            i++;
        }
        if (i % 2 == 0) {
            sign = true;
        } else {
            sign = false;
        }
        s = s.substr(i);
        data = s;
        clear();
    }

    // 构造函数
    explicit BigInteger(long n) {
        string s = to_string(n);
        int i = 0;
        while (s[i] == '-') {
            i++;
        }
        if (i % 2 == 0) {
            sign = true;
        } else {
            sign = false;
        }
        s = s.substr(i);
        data = s;
        clear();
    }

    [[nodiscard]] int size() const {
        return (int) data.size();
    }

    void clear() {
        clearT(data);
        if (data == "0") {
            sign = true;
        }
    }

    static void clearK(string&str) {
        int n = (int) str.size();
        if (2 * k >= n) {
            return;
        }
        string copy;
        for (int i = 0; i < 2 * k && i < n; i++) {
            copy += str[n - 1 - i];
        }
        reverse(copy.begin(), copy.end());
        str = copy;
    }

    static void clearT(string&str) {
        clearK(str);
        if (str.empty()) {
            str = "0";
            return;
        }
        int i = 0;
        while (i < str.size() - 1 && str[i] == '0') {
            i++;
        }
        str = str.substr(i);
    }

    static string multiplyAbs(string a, string b) {
        clearT(a);
        clearT(b);
        int len1 = (int) a.size();
        int len2 = (int) b.size();
        string res(len1 + len2, '0');
        for (int i = len1 - 1; i >= 0; i--) {
            int carry = 0;
            for (int j = len2 - 1; j >= 0; j--) {
                carry += (a[i] - '0') * (b[j] - '0') + (res[i + j + 1] - '0');
                res[i + j + 1] = (char) (carry % 10 + '0');
                carry /= 10;
            }
            res[i] = (char) (res[i] + carry);
        }
        clearT(res);
        return res;
    }

    // 封装乘法方法,返回一个新的 BigInteger 类型
    [[nodiscard]] BigInteger multiply(const BigInteger&num) const {
        if (sign == num.sign) {
            return BigInteger(multiplyAbs(data, num.data));
        } else {
            return BigInteger("-" + multiplyAbs(data, num.data));
        }
    }

    [[nodiscard]] BigInteger pow(long long num) const {
        BigInteger res(1);
        BigInteger bas = *this;
        while (num > 0) {
            if (num % 2 == 1) {
                res *= bas;
            }
            bas *= bas;
            num /= 2;
        }
        return res;
    }

    // 重载乘法运算符 *
    BigInteger operator*(const BigInteger&num) const {
        return multiply(num);
    }

    void operator*=(const BigInteger&num) {
        *this = *this * num;
    }

    char& operator[](int index) {
        return data[index];
    }

    friend istream& operator>>(istream&is, BigInteger&num) {
        string s;
        is >> s;
        num = BigInteger(s);
        return is;
    }

    // 重载输出运算符 <<,输出格式同上
    friend ostream& operator<<(ostream&os, const BigInteger&num) {
        os << num.data;
        return os;
    }
};

void solve() {
    string it;
    cin >> it >> k;
    BigInteger n(it);
    BigInteger mul = n;
    BigInteger ans(1);
    for (int i = 0; i < k; i++) {
        BigInteger temp = n;
        bool notfound = true;
        int j = 1;
        for (; j <= 10; j++) {
            temp *= mul;
            if (temp[temp.size() - 1 - i] == n[n.size() - 1 - i]) {
                ans *= BigInteger(j);
                notfound = false;
                break;
            }
        }
        if (notfound) {
            cout << "-1" << endl;
            return;
        }
        mul = mul.pow(j);
    }
    cout << ans << endl;
}

auto main() -> signed {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值