Codeforces Round 912 (Div. 2)补题B、C、D1

Codeforces Round 912 (Div. 2)

B. StORage room

思路

\(a_i\) = \(M_i\)\(_1\) & \(M_i\)\(_2\) & \(M_i\)\(_3\) & ...& \(M_i\)\(_n\) \((i != j)\)

ac代码

#include <bits/stdc++.h>

using namespace std;
using i64  = long long;
const i64 inf = 8e18;
typedef pair<int, int> pii;
const int N = 3e5 + 10;

void solve() {
    int n;
    cin >> n;
    int a[n + 10][n + 10];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> a[i][j];

    vector<int> res(n, (1 << 30) - 1);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
            //cin >> a[i][j];
            if (i == j) continue;
            res[i] &= a[i][j];
            res[j] &= a[i][j];
        }

    bool ok = 1;
    for (int i = 0; i < n; i++) 
        for (int j = 0; j < n; j++) {
            if (i == j) continue;
            if ((res[i] | res[j]) != a[i][j]) ok = 0;
        }

    if (ok) {
        cout << "YES\n";
        for (int i = 0; i < res.size(); i++)
            cout << res[i] << " \n"[i + 1 == res.size()];
        //cout << endl;
    }else cout << "NO\n";
}

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

    int t = 1;
    cin >> t;
    while (t --) solve();

    return 0;
}

C. Theofanis' Nightmare

思路

当后缀和为正时就划分

ac代码

#include <bits/stdc++.h>

using namespace std;
using i64  = long long;
const i64 inf = 8e18;
typedef pair<int, int> pii;
const int N = 3e5 + 10;

void solve() {
    int n;
    cin >> n;
    vector<i64> v(n + 1), suf(n + 1);
    for (int i = 0; i < n; i++) cin >> v[i];
    for (int i = n - 1; i >= 0; i --) suf[i] = suf[i + 1] + v[i];

    i64 ans = 0, cnt = 0;
    for (int i = 0; i < n; i++) {
        if (i == 0 || suf[i] > 0) cnt ++;
        ans += cnt * v[i];
    }

    cout << ans << endl;
}

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

    int t = 1;
    cin >> t;
    while (t --) solve();

    return 0;
}

D1. Maximum And Queries (easy version)

思路

位运算的贪心我们要从高位开始做。
我们要从最高位去构造答案。先去遍历一下数组中的元素对当前构造的位有多少贡献,如果贡献小于最大操作数,那么当前构造的位就可以被构造出来,

ac代码

#include <bits/stdc++.h>

using namespace std;
using i64  = long long;
const i64 inf = 8e18;
typedef pair<int, int> pii;
const int N = 3e5 + 10;

void solve() {
    int n, q;
    cin >> n >> q;
    vector<i64> a(n), b;
    for (auto &i : a) cin >> i;

    while (q --) {
        i64 ans = 0;
        i64 m; cin >> m;
        b = a;  
        for (int k = 59; k >= 0; k --) {
            i64 sum = 0;
            for (int i = 0; i < n; i ++) {
                if ((b[i] >> k) & 1 ^ 1) 
                    sum += (1ll << k) - b[i];
                if (sum > m) break;
            }

            if (m >= sum) {
                m -= sum;
                ans += 1ll << k;
                for (int i = 0; i < n; i++)
                    if ((b[i] >> k) & 1 ^ 1) b[i] = 0;//将对sum有贡献置为0,比如0010 -> 1000,最高位已经用过了,且后面的位都为0,所以置为0
            }

            for (int i = 0; i < n; i++) {
                if ((b[i] >> k) & 1) b[i] ^= (1ll << k);//高位已经用完了,后面不需要,所以减去
            }
        }

        cout << ans << endl;
    }
}

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

    int t = 1;
    //cin >> t;
    while (t --) solve();

    return 0;
}
posted @ 2023-12-04 18:34  jvdyvan  阅读(92)  评论(0)    收藏  举报