zoukankan      html  css  js  c++  java
  • Codeforces Global Round 14

    Codeforces Global Round 14

    A - Phoenix and Gold

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> m;
            rep (i, 1, n) cin >> a[i];
            sort(a + 1, a + 1 + n);
            int x = 1, s = 0; queue<int> q;
            for (; x <= n; ++x) {
                s += a[x];
                if (s == m && q.empty() && x == n) break;
                else if (s == m && (q.empty() || q.front() == a[x])) {
                    int y = x + 1;
                    while (y <= n && a[y] == a[x]) ++y;
                    if (y > n) break;
                    q.push(a[y]);
                    while (x < y) q.push(a[x++]), s += a[x];
                }
                else if (s == m && x == n) break;
                else if (s == m) {
                    q.push(a[x]); q.push(a[++x]); q.push(q.front());
                    q.pop(); s += a[x];
                }
                else q.push(a[x]);
            }
            if (s == m) cout << "NO
    ";
            else {
                cout << "YES
    ";
                while (!q.empty()) cout << q.front() << ' ', q.pop();
                cout << '
    ';
            }
        }
        return 0;
    }
    

    B - Phoenix and Puzzle

    int main() {
        IOS; set<int> st; n = 1;
        while (1) {
            st.insert(n * n); ++n;
            if (n >= 1e9 / n) break;
        }
        for (cin >> _; _; --_) {
            cin >> n;
            if (n & 1) cout << "NO
    ";
            else if (st.count(n >> 1)) cout << "YES
    ";
            else if (n >> 1 & 1) cout << "NO
    ";
            else if (st.count(n >> 2)) cout << "YES
    ";
            else cout << "NO
    ";
        }
        return 0;
    }
    

    C - Phoenix and Towers

    贪心

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            priority_queue<PII> q;
            cin >> n >> m >> k; cout << "YES
    ";
            rep (i, 1, m) q.push({ 0, i });
            rep (i, 1, n) {
                cin >> cas;
                auto x = q.top(); q.pop();
                cout << x.se << ' ';
                x.fi -= cas; q.push(x);
            }
            cout << '
    ';
        }
        return 0;
    }
    

    D - Phoenix and Socks

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> k >> n >> m; map<int, int> a, b;
            int x = n, y = m, d = 0;
            rep (i, 1, n) cin >> cas, ++a[cas];
            rep (i, 1, m) {
                cin >> cas;
                if (a[cas]) --a[cas], --x, --y;
                else ++b[cas];
            }
            if (x == y) { cout << x << '
    '; continue; }
            if (x < y) swap(a, b), swap(x, y);
            for (auto &i : a) d += i.se >> 1;
            if (d >= x - y >> 1) cout <<  y + (x - y >> 1) << '
    ';
            else cout << y + (x - y - d * 2) + d << '
    ';
        }
        return 0;
    }
    

    E - Phoenix and Computers

    线性dp

    首先, 假设开([l, r]) 开了 (r-l+1) 台电脑, 则必定是从一台电脑, 不断左右边界反复横跳开电脑

    即方案数为(2^{r-l+1})

    当使用题目给的自动开启方案时, 注意到按区间dp的话

    ([l, k], [k + 2, g], [g + 2, r])([k + 2, g]) 归于左边(([l, k], [k + 2, r]))或右边(([l, g], [g + 2, r])) 都是可行的

    但会多算

    故我们在扩展范围的时候除了不使用自动开启方案, 则保证扩展的部分([k, r]) 没用使用自动开启

    则每次扩展扩展使用一次自动开启([l, k], [k + 2, r]), 去重, 变成了线性dp

    (f(i, j)) 表示前(i) 台电脑手动开了 (j) 次,

    (f(i, i) = 2^{i - 1})

    (f(i + 1 + k, j + k) += f(i, j) * 2^{k - 1} * C_{j + k}^{k})

    int mod, f[N][N], qp[N];
    int fac[N], facinv[N], inv[N];
    
    int C(int n, int m) { return (ll)fac[n] * facinv[m] % mod * facinv[n - m] % mod; }
    
    void init(int n) {
        fac[0] = fac[1] = facinv[0] = facinv[1] = inv[0] = inv[1] = qp[0] = 1; qp[1] = 2;
        rep (i, 2, n)
            qp[i] = (ll)(qp[i - 1] << 1) % mod,
            fac[i] = (ll)fac[i - 1] * i % mod,
            inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod,
            facinv[i] = (ll)facinv[i - 1] * inv[i] % mod;
    }
    
    int main() {
        IOS; cin >> n >> mod; init(n);
        rep (i, 1, n) f[i][i] = qp[i - 1];
        rep (i, 1, n) rep (j, 1, n) rep (k, 1, n - 1 - i)
            f[i + k + 1][j + k] = (f[i + k + 1][j + k] + (ll)f[i][j] * qp[k - 1] % mod * C(j + k, k) % mod) % mod;
        rep (i, 1, n) m = (m + f[n][i]) % mod; cout << m;
        return 0;
    }
    

    注意到当 (sum a_i geqslant x imes (n - 1)) 必定有解

    可用归纳法和反证法

    否则无解

    就变成了选编的顺序

    毕竟是颗树, 那就dfs完事

    到达叶子节点

    如果(a_i geqslant x) 则这条边肯定先选择, 并且把多余的 (a_i - x) 水泥贡献给父亲节点

    否则 这条边最后选(最后的时候, 多余的水泥会从父亲节点传过来)

    ll a[N], s;
    int ans[N], l, r, g[N][2];
    VI h[N];
    bool v[N];
    
    int get(int x, int e) { return g[e][0] ^ g[e][1] ^ x; }
     
    void dfs(int x, int e) {
    	v[x] = 1;
    	for (auto &id : h[x]) if (!v[get(x, id)]) dfs(get(x, id), id);
    	if (!e) return;
    	if (a[x] >= k) ans[++l] = e, a[get(x, e)] += a[x] - k;
    	else ans[--r] = e;
    }
    
    int main() {
        IOS; cin >> n >> m >> k; r = n;
        rep (i, 1, n) cin >> a[i], s += a[i];
        if (n - 1 > s / k) return cout << "NO
    ", 0;
        rep (i, 1, m) rep (j, 0, 1) cin >> g[i][j], h[g[i][j]].pb(i);
        dfs(1, 0); cout << "YES
    ";
        rep (i, 1, n - 1) cout << ans[i] << '
    ';
        return 0;
    }
    
  • 相关阅读:
    PLECS—晶闸管-第九周
    第五六周读书笔记
    PLEC-交流电机系统+笔记
    直流电机交流电机读书笔记-4
    PLECS—直流电机系统2
    自动化技术中的进给电气传动-读书笔记3
    文档保存
    TensorFlow安装教程(CPU版)
    团队项目开发日志--(第四篇)
    团队项目开发日志--(第三篇)
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14727379.html
Copyright © 2011-2022 走看看