Link

A

并查集,求权值前 大的联通块。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

#define range(a) begin(a), end(a)

struct UnionFind {
    int n;
    vector<int> f;
    UnionFind(const int &n = 0) : n(n), f(n) {
        iota(f.begin(), f.end(), 0);
    }
    int get(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }
    bool unite(int x, int y) {
        x = get(x), y = get(y);
        if (x != y) {
            f[y] = x;
            return 1;
        }
        return 0;
    }
    bool united(int x, int y) {
        return get(x) == get(y);
    }
};

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

    int n, m, k, w;
    cin >> n >> m >> k >> w;

    vector<int> a(n), b(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> b[i];
    }

    UnionFind f(n);
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;

        u--, v--;
        if (b[u] == b[v]) {
            f.unite(u, v);
        }
    }
    
    vector<i64> sz(n);
    for (int i = 0; i < n; i++) {
        int j = f.get(i);
        if (b[j] == 1) {
            sz[j] += a[i];
        }
    }
    sort(range(sz), greater());

    i64 ans = 0;
    k = max(1, k);
    for (int i = 0; i < k; i++) {
        ans += sz[i];
    }
    cout << ans << '\n';    

    return 0;
}

B

对于 ,有 三种状态,没有被两个区间中的任何一个区间覆盖,只被两个区间中的一个区间覆盖,同时被两个区间覆盖,前缀和。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

constexpr int P = 1000000007;
constexpr int N = 5E5;

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

    int n;
    cin >> n;

    vector<int> pw(n + 1);
    pw[0] = 1;
    for (int i = 0; i < n; i++) {
        pw[i + 1] = pw[i] * 2LL % P;
    }    

    vector<int> l1(n), l2(n), r1(n), r2(n);
    for (int i = 0; i < n; i++) {
        cin >> l1[i] >> r1[i] >> l2[i] >> r2[i];
    }

    vector<vector<int>> d(3, vector<int>(N + 1));
    for (int i = 0; i < n; i++) {
        vector<array<int, 2>> f;
        f.push_back({l1[i], 1});
        f.push_back({r1[i] + 1, -1});
        f.push_back({l2[i], 1});
        f.push_back({r2[i] + 1, -1});
        sort(f.begin(), f.end());
        int lst = 0;
        int val = 0;
        for (auto [x, v] : f) {
            if (lst < x) {
                d[val][lst]++;
                d[val][x]--;
            }
            val += v;
            lst = x;
        }
        d[0][lst]++;        
    }
    
    for (int i = 0; i < 3; i++) {
        for (int j = 1; j <= N; j++) {
            d[i][j] += d[i][j - 1];
        }
    }

    i64 ans = 0;
    for (int x = 0; x <= N; x++) {
        if (d[0][x] == 0) {
            ans = (ans + pw[d[2][x]]) % P;
        }
    }    
    cout << ans << '\n';

    return 0;
}

D

先做一次指令,可以到达 ,然后再跑一次就是

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

void solve() {
    int x, y, k;
    cin >> x >> y >> k;
    
    string s;
    cin >> s;
    int n = s.size();

    if (!x && !y) {
        cout << "Yes\n";
        return;
    }

    int sx = 0, sy = 0;

    for (int i = 0; i < n; i++) {
        if (s[i] == 'U') {
            sy++;
        } else if (s[i] == 'D') {
            sy--;
        } else if (s[i] == 'L') {
            sx--;
        } else {
            sx++;
        }

        if (sx == x && sy == y) {
            cout << "Yes\n";
            return;
        }
    }   

    if (!sx && !sy) {
        cout << "No\n";
        return;
    }

    int tx = 0, ty = 0;

    for (int i = 0; i < n; i++) {
        if (s[i] == 'U') {
            ty++;
        } else if (s[i] == 'D') {
            ty--;
        } else if (s[i] == 'L') {
            tx--;
        } else {
            tx++;
        }

        int dx = x - tx, dy = y - ty;     
        
        if (dx && (!sx || dx % sx)) {
            continue;
        }
        if (dy && (!sy || dy % sy)) {
            continue;
        }

        int cx = sx ? dx / sx : 0;
        int cy = sy ? dy / sy : 0;
        
        if ((!cx || !cy || cx == cy) && cx >= 0 && cx < k && cy >= 0 && cy < k) {
            cout << "Yes\n";
            return;
        }
    }
    cout << "No\n";
}

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

    int t;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

E

计算几何。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

using Point = complex<double>;
const double Pi = acos(-1.0);
constexpr double eps = 1E-9;

Point rotate(const Point &p, const double &rad) {
    return p * Point(cos(rad), -sin(rad));
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(2);

    int n;
    cin >> n;
    Point v = Point(0, n * (cos(0.1 * Pi) + sin(0.1 * Pi) / tan(0.2 * Pi)));
    Point p = Point(0, -n * sin(0.1 * Pi) / tan(0.2 * Pi));

    for (int i = 0; i < 5; i++) {
        v = rotate(v, 0.4 * Pi);
        cout << char('A' + i) << ": ";
        auto a = p + v;
        cout << real(a) + eps << ' ' << imag(a) + eps << '\n';
    }
    
    return 0;
}

F

可以用 表。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

template <class T>
struct SparseTable {
    int n;
    vector<vector<T>> a;
    function<T(T, T)> func = [](const T &a, const T &b) {
        return a | b;  
    };
    SparseTable(const vector<T> &init) : n(init.size()) {
        int lg = __lg(n);
        a.assign(lg + 1, vector<T>(n));
        a[0] = init;
        for (int i = 1; i <= lg; i++) {
            for (int j = 0; j <= n - (1 << i); j++) {
                a[i][j] = func(a[i - 1][j], a[i - 1][(1 << (i - 1)) + j]);
            }
        }  	    
    }
    T get(int l, int r) { // [l, r)
        int lg = __lg(r - l);
        return func(a[lg][l], a[lg][r - (1 << lg)]);
    }
};

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

    int n, m;
    cin >> n >> m;

    vector<i64> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    SparseTable<i64> st(a);
    for (int i = 0; i < m; i++) {
        int l, r;
        i64 x;
        cin >> l >> r >> x;
        l--;
        cout << (st.get(l, r) | x) << '\n';
    }

    return 0;
}

G

栈。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

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

    string a, b, s;
    cin >> a >> b >> s;
    int n = s.size();
  
    unordered_map<char, char> mp, id;
    for (int i = 0; i < 13; i++) {
        mp[b[i]] = a[i];
        id[b[i]] = i + 1;
    }
                           
    vector<int> st;
    int pre = 0;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (mp.count(s[i]) && !st.empty() && mp[s[i]] == s[st.back()] && id[s[i]] >= pre) {
            int res = i - st.back() + 1;
            if (res >= 4) {
                ans = max(ans, res);
            }
            st.pop_back();
            pre = id[s[i]];
        } else {
            if (!st.empty() && st.back() != i - 1) {
                st = {};
            }
            st.push_back(i);
            pre = 0;
        }
    }
    cout << ans << '\n';
    
    return 0;
}

I

素性测试。

K

线性筛,前缀和。

C++ Code
#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

#define range(a) begin(a), end(a)

vector<int> isprime, primes;
 
void sieve(int n) {
    isprime.assign(n + 1, 1);
    isprime[0] = isprime[1] = 0;
    
    for (int i = 2; i <= n; i++) {
        if (isprime[i]) {
            primes.push_back(i);
        }
        
        for (auto p : primes) {
            if (i * p > n) {
                break;
            }
            isprime[i * p] = 0;
            if (i % p == 0) {
                break;
            }
        }
    }
}


void solve() {
    int l, r;
    cin >> l >> r;
    cout << isprime[r] - isprime[l - 1] << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    sieve(1E6);
    partial_sum(range(isprime), isprime.begin());

    int t;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}