代码源挑战赛 Round 1

#1. [R1A]最大奇数

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    int res = -1;
    for (int i = 1, x; i <= n; i++) {
        cin >> x;
        if (x % 2 == 0) continue;
        res = max(res, x);
    }
    cout << res << "\n";
    return 0;
}

#2. [R1B]砖块覆盖

对于行列均为偶数的情况可以用\(2\times 2\)拼出来。

对于行列有一个为偶数的情况,可以先用\(2\times 2\)拼,然后剩下一个\(1\times n\)的情况,并且\(n\)一定是偶数。

对于行列都是奇数,用\(2\times 2\)评完后,还剩下\(1\times n , 1\times (n - 1)\),因此无法拼成剩下的。

所有行列全奇数为No,剩下全是Yes

#include <bits/stdc++.h>

using namespace std;

void solve(){
    int x, y;
    cin >> x >> y;
    if ((x % 2) and (y % 2)) cout << "No\n";
    else cout << "Yes\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while(T --) solve();
    return 0;
}

#3. [R1C]区间求和

计算每一个数被多少个区间包含。

#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    i64 res = 0;
    for(int i = 1; i <= n ; i ++) {
        i64 x;
        cin >> x;
        res += x * (i) * (n - i + 1);
    }
    cout << res;
    return 0;
}

#4. [R1D]传送

每一个点只有一个唯一后继,所以图是一个内向基环树。用类似倍增求LCA的方式预处理在图上移动。

#include <bits/stdc++.h>

using i64 = int64_t;
using vi = std::vector<int>;
using std::cin, std::cout;

int main() {
    std::ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    std::vector next(n + 1, vi(31));
    for (int i = 1; i <= n; i++) {
        cin >> next[i][0];
    }
    for (int j = 1; j < 31; j++)
        for (int i = 1; i <= n; i++)
            next[i][j] = next[next[i][j - 1]][j - 1];

    int q;
    cin >> q;
    for (int x, t; q; q--) {
        cin >> x >> t;
        for (int i = 0; i < 31 and t > 0; i++) {
            if (t & 1) x = next[x][i];
            t >>= 1;
        }
        cout << x << "\n";
    }

    return 0;
}

#5. [R1E]过分的子区间

“过分的区间”可以理解为,区间中比\(x\)小的数小于\(k\)个。

这样的话,如果\([l,r]\)满足,则\([l,r-1]\)也满足,固定左端点,右端点满足二分性。

用前缀和维护出区间中小于\(x\)的数的个数。

#include <bits/stdc++.h>

using i64 = int64_t;
using vi = std::vector<int>;
using std::cin, std::cout;

int main() {
    std::ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, k, z;
    cin >> n >> k >> z;
    vi pre(n + 1);
    for (int i = 1, x; i <= n; i++) {
        cin >> x;
        if (x < z) pre[i] = 1;
    }
    for (int i = 1; i <= n; i++) pre[i] += pre[i - 1];

    i64 res = 0;
    for (int i = 1, ans, l, r, mid; i <= n; i++) {
        l = i - 1, r = n, ans = -1;
        while (l <= r) {
            mid = (l + r) / 2;
            if (pre[mid] - pre[i - 1] < k) ans = mid, l = mid + 1;
            else r = mid - 1;
        }
        res += ans - i + 1;
    }
    cout << res;
    return 0;
}

#6. [R1F]重复度不超过k的数

dp

\(f[i][j]\)表示前\(i\)个数字,用了\(j\)位的方案数。枚举当前数字用来\(l\)位,则从\(f[i-1][j - l]\)转移过来,填数字前有\(n - j + l\)个位置,选择\(l\)个位置,所以当前数字放置方法有\(C_{n - j + l} ^{l}\)种。

#include <bits/stdc++.h>

using i64 = int64_t;
using vi = std::vector<i64>;
using std::cin, std::cout;

const i64 mod = 998244353;

i64 power(i64 x, i64 y) {
    i64 ans = 1;
    while (y) {
        if (y & 1) ans = ans * x % mod;
        x = x * x % mod;
        y /= 2;
    }
    return ans;
}

vi fact, invFact;


void init(int N) {
    fact.resize(N + 1);
    invFact.resize(N + 1);
    fact[0] = 1;
    for (int i = 1; i <= N; i++) fact[i] = fact[i - 1] * i % mod;
    invFact[N] = power(fact[N], mod - 2);
    for (int i = N; i >= 1; i--) invFact[i - 1] = invFact[i] * i % mod;
}


i64 C(int x, int y) {
    return fact[x] * invFact[x - y] % mod * invFact[y] % mod;
}

int main() {
    std::ios::sync_with_stdio(false), cin.tie(nullptr);

    int n, m, k;
    cin >> n >> m >> k;
    init(n);
    std::vector f(m + 1, vi(n + 1));
    f[0][0] = 1;
    for (int i = 1; i <= m; i++)
        for (int j = 0; j <= k; j++)
            for (int l = j; l <= n; l++)
                f[i][l] = (f[i][l] + f[i - 1][l - j] * C(n - l + j, j)) % mod;
    cout << f[m][n];
    return 0;
}
posted @ 2025-05-09 00:35  PHarr  阅读(117)  评论(0)    收藏  举报