求问
查看原帖
求问
1471689
ztd___楼主2025/8/4 21:05

::::info[这是我的代码] 其中 p(x, pos) 表示 xx 在二进制下的第 pospos 位,c(x) 表示 xx 在二进制下的位数。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 66;
int n, m, a[N], mx, ANS = 1e18;
int p(int x, int pos) { return pos >= 1 ? (x >> (pos - 1) & 1) : 0; }
int c(int x) {
    int t = x, cnt = 0;
    while (t) cnt++, t >>= 1;
    return cnt;
}
void dfs(int op, int step) {
    if (step == n + 1) {
        int u = 0;
        for (int i = 1;i <= n;i++)
            u |= a[i];
        ANS = min(ANS, u);
    } else {
        for (int i = 0;i <= op;i++) {
            a[step] <<= i;
            dfs(op - i, step + 1);
            a[step] >>= i;
        }
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for (int i = 1;i <= n;i++)
        cin >> a[i], mx = max(mx, c(a[i]));
    cin >> m;
    if (n <= 8 && m <= 8) {
        dfs(m, 1);
        cout << ANS;
        return 0;
    }
    sort(a + 1, a + 1 + n, greater<int>());
    int pos = 1;
    while (pos <= n && c(a[pos]) == mx) pos++;
    if (pos > n) {
        int ans = 0;
        for (int i = 1;i <= n;i++)
            ans |= a[i];
        cout << ans;
    } else {
        int ans = 0;
        for (int i = 1;i < pos;i++)
            ans |= a[i];
        vector<int> z;
        for (int j = mx - 1;j >= 1;j--) {
            if (p(ans, j) == 1) continue;
            int sum = 0;
            for (int i = pos;i <= n;i++) {
                if (p(a[i], j) == 0) continue;
                for (int k = j - 1;c(a[i]) + j - k <= mx;k--) {
                    if (p(a[i], k) == 1) continue;
                    int cost = j - k, flg = 0;
                    int num = (a[i] << cost);
                    for (auto o : z)
                        if (p(num, o) == 1) { flg = 1; break; }
                    if (flg == 0) { sum += cost; break; }
                }
            }
            if (sum <= m) {
                m -= sum;
                for (int i = pos;i <= n;i++) {
                    if (p(a[i], j) == 0) continue;
                    for (int k = j - 1;c(a[i]) + j - k <= mx;k--) {
                        if (p(a[i], k) == 1) continue;
                        int cost = j - k, flg = 0;
                        int num = (a[i] << cost);
                        for (auto o : z)
                            if (p(num, o) == 1) { flg = 1; break; }
                        if (flg == 0) { a[i] = num; break; }
                    }
                }
                int chk = 0;
                for (int i = pos;i <= n;i++)
                    chk |= p(a[i], j);
                if (chk == 0) z.push_back(j); 
            }
        }
        for (int i = pos;i <= n;i++)
            ans |= a[i];
        cout << ans;
    }
    return 0;
}

::::

我的问题(主要是 2, 问题 1 我可以慢慢调):

  1. 如果删去 n8n \le 8m8m \le 8 的爆搜,我的代码会在 Sub1 的第一个点 WA,请问是哪里出现了问题?
  2. 在我看来,我的代码应该是带了不止一个 log\log 的,最慢应该是 3log,但是好像跑的并不慢,请问是复杂度的问题还是写法的问题?换个问法,我的代码的复杂度是否应当过题?

求解答。

2025/8/4 21:05
加载中...