A. Election 2

模拟

代码实现
n, t, a = map(int, input().split())
x = n-t-a
if t+x > a and t < a+x: print('No')
else: print('Yes')

B. Vertical Writing

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int n;
    cin >> n;
    
    vector<string> s(n);
    rep(i, n) cin >> s[i];
    
    int m = 0;
    rep(i, n) m = max(m, (int)s[i].size());
     
    vector<string> t(m, string(n, '*'));
    rep(i, n)rep(j, s[i].size()) {
        t[j][n-1-i] = s[i][j];
    }
    rep(i, m) {
        while (t[i].back() == '*') t[i].pop_back();
        cout << t[i] << '\n';
    }
    
    return 0;
}

C. Balls and Bag Query

可以开一个数组 cnt 来记录每个数 \(x\) 的个数,考虑 cnt[x] 加减 \(1\) 后对答案的影响

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int q;
    cin >> q;
    
    vector<int> cnt(1000001);
    int ans = 0;
    rep(qi, q) {
        int type;
        cin >> type;
        if (type == 3) {
            cout << ans << '\n';
        }
        else {
            int x;
            cin >> x;
            if (type == 1) {
                if (cnt[x] == 0) ans++;
                cnt[x]++;
            }
            else {
                cnt[x]--;
                if (cnt[x] == 0) ans--;
            }
        }
    }
    
    return 0;
}

D. Cuboid Sum Query

三维前缀和,简单容斥一下即可

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int a[101][101][101];
int s[102][102][102];

int main() {
    int n;
    cin >> n;
    
    rep(i, n)rep(j, n)rep(k, n) cin >> a[i][j][k];
    
    rep(i, n)rep(j, n)rep(k, n) s[i+1][j+1][k+1] = a[i][j][k];
    rep(i, n+1)rep(j, n+1)rep(k, n+1) s[i+1][j][k] += s[i][j][k];
    rep(i, n+1)rep(j, n+1)rep(k, n+1) s[i][j+1][k] += s[i][j][k];
    rep(i, n+1)rep(j, n+1)rep(k, n+1) s[i][j][k+1] += s[i][j][k];
    
    int q;
    cin >> q;
    rep(qi, q) {
        int lx, rx, ly, ry, lz, rz;
        cin >> lx >> rx >> ly >> ry >> lz >> rz;
        --lx; --ly; --lz;
        auto sum_z = [&](int rx, int ry, int lz, int rz) {
            return s[rx][ry][rz] - s[rx][ry][lz];
        };
        auto sum_yz = [&](int rx, int ly, int ry, int lz, int rz) {
            return sum_z(rx, ry, lz, rz) - sum_z(rx, ly, lz, rz);
        };
        auto sum_xyz = [&](int lx, int rx, int ly, int ry, int lz, int rz) {
            return sum_yz(rx, ly, ry, lz, rz) - sum_yz(lx, ly, ry, lz, rz);
        };
        int ans = sum_xyz(lx, rx, ly, ry, lz, rz);
        cout << ans << '\n';
    }
    
    return 0;
}

E. Manhattan Multifocal Ellipse

\( \sum (|x - x_i| + |y-y_i|) = (\sum |x-x_i|) + (\sum |y-y_i|) \)

可以看出 \(x\)\(y\) 彼此相互独立
\(D\)\(x_i\) 的范围可以推出 \(|x| \leqslant 2 \times 10^6\)
\(a[x] = \sum |x-x_i|\)\(b[y] = \sum |y-y_i|\)
那么原问题就转化成了求有多少个二元组 \((i, j)\) 满足 \(a[i] + b[j] \leqslant D\),可以对 \(a\)\(b\) 排序后用双指针来解决
另外,对于 \(a[x]\) 的预处理同样可以用双指针,考虑差分思想,比如从 \(0\) 移动到 \(1\),可以发现 \(0\) 左边的所有 \(x_i\) 会在前面到 \(0\) 的距离的基础上扩张一个单位,\(0\) 右边的所有 \(x_i\) 会在到 \(0\) 的距离的基础上缩短一个单位

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

const int M = 1e6;

vector<ll> f(vector<int> x) {
    int n = x.size();
    rep(i, n) x[i] += M*2;
    ll s = 0;
    rep(i, n) s += x[i];
    vector<ll> res(M*4+1);
    res[0] = s;
    
    ranges::sort(x);
    
    int k = 0;
    for (int i = 1; i <= M*4; ++i) {
        while (k < n and x[k] < i) ++k;
        s -= n-k*2;
        res[i] = s;
    }
    return res;
}

int main() {
    int n, d;
    cin >> n >> d;
    
    vector<int> x(n), y(n);
    rep(i, n) cin >> x[i] >> y[i];
    
    auto a = f(x);
    auto b = f(y);
    ranges::sort(a);
    ranges::sort(b);
    
    ll ans = 0;
    int j = b.size()-1;
    rep(i, a.size()) {
        while (j >= 0 and a[i]+b[j] > d) --j;
        ans += j+1;
    }
    cout << ans << '\n';
    
    return 0;
}

F. Maximum Composition

先确定 \(f\) 的顺序,\(f_j\) 可以排在 \(f_i\) 的前面当且仅当 \(f_i(f_j(x)) > f_j(f_i(x))\)
\( \Leftrightarrow A_i(A_jx + B_j)+B_i > A_j(A_ix + B_i) + B_j \)
\( \Leftrightarrow A_iA_jx + A_iB_j + B_i > A_iA_jx + A_jB_i + B_j \)
\( \Leftrightarrow A_iB_j + B_i > A_jB_i +B_j \)
\( \Leftrightarrow (A_i-1)B_j > (A_j-1)B_i \)
\( \Leftrightarrow \frac{A_i-1}{B_i} > \frac{A_j-1}{B_j} \)

接下来就可以考虑dp了
dp[i][k] 表示到 \(f_i'\) 为止已经选了 \(k\) 个时的最大值

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

struct F {
    ll a, b;
    F(ll a=0, ll b=0): a(a), b(b) {}
    ll operator()(ll x) { return a*x+b; }
};

int main() {
    int n, k;
    cin >> n >> k;
    
    vector<F> f(n);
    rep(i, n) cin >> f[i].a >> f[i].b;
    
    ranges::sort(f, [&](F f1, F f2) {
        return f2(f1(0)) > f1(f2(0));
    });
    
    vector<ll> dp(k+1, 1);
    rep(i, n) {
        vector<ll> old(k+1, 1);
        swap(dp, old);
        rep(j, k+1) {
            dp[j] = max(dp[j], old[j]);
            if (j < k) dp[j+1] = max(dp[j+1], f[i](old[j]));
        }
    }
    
    cout << dp[k] << '\n';
    
    return 0;
}

G. XOR Neighbors

对于异或一般都可以按位考虑,所以首先要考虑在顶点上写 \(0\)\(1\),使得它所有相邻顶点上的点权的异或和为 \(0\) 的方案。
根据条件,可以列出 \(n\) 个方程 \(Ax = 0\) 的方程组。为了构造出一个题目的合法解,每个数中至少应该处理出 \(2\) 位,另外由于右边都是 \(0\),所以不妨分别考虑令每个 \(x_i = 1\),然后用高斯消元法求出一组解,最后再将这些解按位组合起来即可。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

struct Matrix {
    using BS = bitset<61>;
    int h, w;
    vector<BS> d;
    Matrix(int h, int w): h(h), w(w), d(h) {}
    BS operator[](int i) const { return d[i]; }
    BS& operator[](int i) { return d[i]; }
    BS solve() {
        int ni = 0;
        rep(j, w-1) {
            for (int i = ni; i < h; ++i) {
                if (d[i][j]) { swap(d[i], d[ni]); break; }
            }
            if (!d[ni][j]) continue;
            rep(i, h) if (ni != i and d[i][j]) d[i] ^= d[ni];
            ni++;
            if (ni == h) break;
        }
        BS no, res; no[w-1] = 1;
        rep(i, h) {
            int j = 0;
            while (j < w-1 and !d[i][j]) ++j;
            if (j == w-1) {
                if (d[i][w-1]) return no;
                continue;
            }
            res[j] = d[i][w-1];
        }
        return res;
    }
};

int main() {
    int n, m;
    cin >> n >> m;
    
    Matrix d(n+1, n+1);
    rep(i, m) {
        int u, v;
        cin >> u >> v;
        --u; --v;
        d[u][v] = 1;
        d[v][u] = 1;
    }
    
    vector<ll> ans(n);
    rep(i, n) {
        Matrix = d;
        nd[n][i] = 1; nd[n][n] = 1;
        auto sol = nd.solve();
        if (sol[n]) {
            puts("No");
            return 0;
        }
        rep(j, n) if (sol[j]) ans[j] |= 1ll<<i;
    }
    
    puts("Yes");
    rep(i, n) cout << ans[i] << ' ';
    
    return 0;
}