Codeforces Round 921 (Div. 2)

https://codeforces.com/contest/1925

恶心round,从C题开始每题都是一眼看出做法但是细节挺多的题,烦的一比。

A. We Got Everything Covered! *800

给定 n,k,若所有长度为 n 且仅由字母表中前 k 个小写字母组成的串都是 s 的子序列,则称 s 是 "Everything Covered" 的。请构造串 s

这样构造:abcdabcdabcd

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int n, k;
    cin >> n >> k;
    while (n--) {
        for (int i = 0; i < k; i++)
            cout << char('a' + i);
    }
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T; cin >> T; while (T--)
        sol();
}

B. A Balanced Problemset? *1200

x 分成 n 个大于零的数之和,这些数的 gcd 最大是多少?

x108

这些数都能表示成它们的 gcd 的倍数,gcd 必是 x 的因子,枚举因子即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int x, n;
    cin >> x >> n;
    vector<int> d;
    for (int i = 1; i <= x / i; i++) {
        if (x % i) continue;
        d.push_back(i);
        if (i != x / i) d.push_back(x / i);
    }
    sort(d.begin(), d.end());
    for (int di : d) {
        if (di >= n) return cout << x / di << '\n', void();
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T; cin >> T; while (T--)
        sol();
}

C. Did We Get Everything Covered? *1500

判断给定串是不是 "Everything Covered" 的。如果不是,构造反例。

这样构造反例:每次选“最晚出现的字符”

感觉这个人的方法比我帅多了 https://zhuanlan.zhihu.com/p/680178758

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int n, k, m;
    string s;
    cin >> n >> k >> m >> s;
    vector<int> p(k, m), f(m); //后缀中首次出现位置最晚的字符出现的位置
    for (int i = m - 1; ~i; i--) {
        p[s[i] - 'a'] = i;
        for (int j : p) f[i] = max(f[i], j);
    }
    
    string ans;
    for (int i = 0; i < m; i++) {
        if (f[i] < m) {
            ans += s[f[i]];
            i = f[i];
            if (ans.size() == n)
                return cout << "YES\n", void();
        } else {
            vector<bool> occ(k);
            for (int j = i; j < m; j++)
                occ[s[j] - 'a'] = true;
            int c = 0; while (occ[c]) c++;
            while (ans.size() < n) ans += char(c + 'a');
            cout << "NO\n" << ans << '\n';
            return;
        }
    }
    while (ans.size() < n) ans += 'a';
    cout << "NO\n" << ans << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T; cin >> T; while (T--)
        sol();
}

D. Good Trip *1900

n 个同学,其中有 m 对朋友,第 i 对朋友有友谊值 fi。老师每次随机(从所有 Cn2 对中)选一对人,共选 k 次。一对朋友被选中后,答案加上他们当前的友谊值,然后他们的友谊值增加 1。问答案的期望。

n,m1e5,k2e5

考虑第 i 对朋友对答案的贡献。fi 被加入答案的概率为 P(1)fi+1 被加入答案的概率为 P(2),以此类推。

P(x) 为第 i 对朋友被选择的次数 x 的概率,P(x)=j=xkCkjpj(1p)kj,其中 p=1/Cn2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int P = 1e9 + 7;
const int N = 2e5 + 5;

ll fac[N], ifac[N];

ll qmi(ll a, ll b) {
    ll s = 1;
    for (; b; b >>= 1) {
        if (b & 1) s = s * a % P;
        a = a * a % P;
    }
    return s;
}

ll C(ll n, ll k) {
    if (n < k) return 0;
    return fac[n] * ifac[k] % P * ifac[n - k] % P;
}

void sol() {
    ll n, m, k;
    cin >> n >> m >> k;
    
    ll sp = 0, sip = 0, ans = 0;
    
    ll p = qmi(n * (n - 1) / 2 % P, P - 2), q = (1 - p + P) % P;
    
    for (ll i = k, s = 0; i; i--) {
        (s += C(k, i) * qmi(p, i) % P * qmi(q, k - i) % P) %= P;
        (sp += s) %= P;
        (sip += i * s % P) %= P;
    }
    
    for (int i = 0; i < m; i++) {
        ll a, b, f;
        cin >> a >> b >> f;
        ans += (f - 1) * sp % P + sip;
    }
    cout << (ans % P + P) % P << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    fac[0] = 1;
    for (int i = 1; i < N; i++)
        fac[i] = fac[i - 1] * i % P;
    ifac[N - 1] = qmi(fac[N - 1], P - 2);
    for (int i = N - 1; i; i--)
        ifac[i - 1] = ifac[i] * i % P;
    
    int T; cin >> T; while (T--)
        sol();
}
 

E. Space Harbour *2100

树状数组或者线段树 区间加差分数组、区间求和,把模板题代码拉过来微调一下就行

牛牛的等差数列(树状数组,区间加等差数列、区间求和)

我写的是树状数组维护二阶差分

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct BIT {
    int n; vector<ll> tr;
    BIT(int n): n(n), tr(n + 1) {}
    int lowbit(int x) { return x & -x; }
    void add(int p, ll x) { for (; p <= n; p += lowbit(p)) tr[p] += x; }
    ll ask(int p) { ll s = 0; for (; p > 0; p -= lowbit(p)) s += tr[p]; return s; }
};

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int n, m, q;
    cin >> n >> m >> q;
    
    BIT c(n), kc(n), kkc(n);
    auto add = [&](int p, ll x) { //对c数组的单点加
        c.add(p, x); kc.add(p, x * p); kkc.add(p, x * p * p);
    };
    auto upd = [&](int l, int r, ll a, ll d) { //a数组区间加等差数列
        add(l, a);
        add(l + 1, d - a);
        add(r + 1, -(a + d * (r - l + 1)));
        add(r + 2, (a + d * (r - l)));
    };
    auto ask = [&](int n) {
        ll s = c.ask(n) * (n + 1) * (n + 2);
        s -= (2 * n + 3) * kc.ask(n);
        s += kkc.ask(n);
        return s / 2;
    };
    
    vector<pair<int, int>> harbour(m);
    for (int i = 0; i < m; i++) cin >> harbour[i].first;
    for (int i = 0; i < m; i++) cin >> harbour[i].second;
    sort(harbour.begin(), harbour.end()); //题目没说港口是有序的...
    
    auto modify = [&](int x1, int v1, int x2, ll ty = 1) { //del=-1表示删除序列
        upd(x1 + 1, x2, ty * v1 * (x2 - x1 - 1), -ty * v1);
    };
    
    set<pair<int, int>> S;
    for (int i = 0; i < m; i++) {
        if (i > 0)
            modify(harbour[i - 1].first, harbour[i - 1].second, harbour[i].first);
        S.insert(harbour[i]);
    }
    
    while (q--) {
        int t; cin >> t;
        if (t == 1) {
            int x, v; cin >> x >> v;
            auto it = S.lower_bound({x, v});
            auto [x2, v2] = *it;
            auto [x1, v1] = *prev(it);
            modify(x1, v1, x2, -1);
            modify(x1, v1, x);
            modify(x, v, x2);
            S.insert({x, v});
        } else {
            int l, r; cin >> l >> r;
            cout << ask(r) - ask(l - 1) << '\n';
        }
    }
    
    return 0;
}
 

F. Fractal Origami *2400 分母有理化

折纸,正方形的纸边长为 1,每次把四个角往内折,得到新的更小的正方形。最后展开,折痕分为峰和谷两类,峰与谷的长度之比 M/V 一定是 A+B2 的形式,A,B 均为有理数。请输出 B

找规律,列式子,分母有理化

拿张纸巾折了几次,发现第 2M,V 均增加 2,第 3M,V 均增加 22。大胆猜测每次 M,V 均增加上次增加长度的 2 倍。然后就是臭不可闻的列式子+疯狂有理化

M=2(2n11)21=2(2n11)(2+1)=2(2n1+2n12)V=M+22=2(2n1+2n1)MV=2n1+2n122n1+2n1

n 为奇数时,

MV=2(n1)/221+2(n1)/222(n1)/221+2(n1)/2

n 为偶数时,

MV=2n/21+2(n2)/2222n/21+2(n2)/22

太丑了,设一下继续算

MV=(x1)2+yx2+y=y2x2y22+

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int P = 999999893;
const int N = 2e5 + 5;

ll fac[N], ifac[N];

ll qmi(ll a, ll b) {
    ll s = 1;
    for (; b; b >>= 1) {
        if (b & 1) s = s * a % P;
        a = a * a % P;
    }
    return s;
}

void sol() {
    ll n;
    cin >> n;
    ll x = qmi(2, n / 2 - !(n & 1)), y = qmi(2, n / 2) - 1;
    cout << (y * qmi((2 * x * x % P - y * y % P) % P, P - 2) % P + P) % P << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);    
    int T; cin >> T; while (T--)
        sol();
}
 
posted @   Bellala  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2022-02-07 cf568 B. Symmetric and Transitive(贝尔数)
点击右上角即可分享
微信分享提示