2021牛客暑期多校训练营2

2021牛客暑期多校训练营2

C - Draw Grids

考虑只有一行时, \(1 \times m\), 只能画 \(m - 1\) 条线

考虑两行\(2 \times m\), 就是\(2 \times (m - 1) + 1 = 2 \times m - 1\), 两行之间多加了一条线

考虑\(n \times m\), 就是\(n \times m - 1\), 你要画另一条线, 必定会取代已经画的一条

int main() {
    IOS;
    cin >> n >> m;
    cout << (n * m & 1 ? "NO" : "YES");
    return 0;
}

D - Er Ba Game

int main() {
    int _;
    for (cin >> _; _; --_) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        if (a > b) swap(a, b);
        if (c > d) swap(c, d);
        int x = 0, y = 0;
        if (a == 2 && b == 8) x = 2;
        else if (a == b) x = 1;
        if (c == 2 && d == 8) y = 2;
        else if (c == d) y = 1;
        if (x > y) cout << "first\n";
        else if (y > x) cout << "second\n";
        else if (x == 1)
            if (a > b) cout << "first\n";
            else if (b > a) cout << "second\n";
            else cout << "tie\n";
        else if ((a + b) % 10 > (c + d) % 10)
            cout << "first\n";
        else if ((a + b) % 10 < (c + d) % 10)
            cout << "second\n";
        else if (b > d) cout << "first\n";
        else if (d > b) cout << "second\n";
        else cout << "tie\n";
    }
    return 0;
}

F - Girlfriend

方程一列, 发现是个关于球的不等式方程, 即这两个人的活动范围是再一个球中, 这题变成了求两个球的并的体积

计算机和, 直接找板子就行了

牛客板子

I - Penguins

爆搜

J -Product of GCD

注意这题卡常, 取膜加法要优化

一看就是容斥

从含有\(x\)作为因子的\(cnt_x\)数中挑选k个, 弄个组合数, \(x^{cnt}\)即可

关键是怎么求\(cnt\), 就是\(C^k_{cnt_x} - C^k_{cnt_{2x}} - ...\)

要求\(2x\)\(cnt\), 又要求\(C^k_{cnt_{2x}} - C^k_{cnt_{4x}} - ...\)

所以倒着求就可以了, 是个调和级数

对于每个数\(x\), 都要求一次快速幂复杂度也是个 \(nlogn\)

至于组合数\(k\)很小, 暴力即可, 复杂度为 \(30 \times n\)

所以复杂度为\(O(nlogn + 30 \times n)\)


K - Stack

模拟

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int n, k;
    cin >> n >> k;
    vector<pair<int, int>> p(k);
    for (auto &i : p) cin >> i.first >> i.second;
    sort(p.begin(), p.end());
    p.emplace_back(n + 1, 1);

    bool f = 0;
    stack<int> st;
    vector<int> a(n);
    for (int i = f = 1, k = 0, j = n; i <= n + 1; ++i) {
        if (k < p.size() && p[k].first == i) {
            if (st.size() + 1 < p[k].second) f = 0;
            while (st.size() >= p[k].second) {
                a[st.top() - 1] = j--;
                st.pop();
            }
            ++k;
        }
        st.push(i);
    }
    if (!f) return cout << "-1", 0;
    for (auto &i : a) cout << i << ' ';
    return 0;
}
posted @ 2021-11-11 11:42  洛绫璃  阅读(45)  评论(0编辑  收藏  举报