QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#367591#7932. AND-OR closuremilmillinWA 1ms3820kbC++143.0kb2024-03-26 09:12:012024-03-26 09:12:02

Judging History

你现在查看的是最新测评结果

  • [2024-03-26 09:12:02]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3820kb
  • [2024-03-26 09:12:01]
  • 提交

answer

#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

bool work[40];
bool imp[40][40];

bool imp2[40][40];

long long cnt[1 << 20];

int main() {
    int n;
    scanf("%d", &n);
    vector<long long> tbl(n);
    for (int i = 0; i < n; i++) {
        scanf("%lld", &tbl[i]);
    }

    for (int i = 0; i < 40; i++) {
        work[i] = true;
    }

    long long full = (1ll << 40) - 1;
    for (int k = 0; k < 40; k++) {
        long long and1 = full;
        bool has0 = false;
        bool has1 = false;
        for (int i = 0; i < n; i++) {
            if (tbl[i] & (1ll << k)) {
                // printf("- %lld\n", tbl[i]);
                and1 &= tbl[i];
                // printf("-> %lld\n", and1);
                has1 = true;
            } else {
                has0 = true;
            }
        }
        // printf("%lld\n", and1);
        for (int j = 0; j < 40; j++) {
            if (j == k) continue;
            if (and1 & (1ll << j)) {
                imp[k][j] = true;
            }
        }
        if (!has0 || !has1) {
            work[k] = false;
        }
    }
    for (int k = 0; k < 40; k++) {
        for (int j = k + 1; j < 40; j++) {
            if (imp[k][j] && imp[j][k]) work[j] = false;
        }
    }
    vector<int> active;
    for (int i = 0; i < 40; i++) {
        if (work[i]) active.push_back(i);
    }
    int m = active.size();
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
            imp2[i][j] = imp[active[i]][active[j]];
            // printf("%d ", (int)imp2[i][j]);
        }
        // printf("\n");
    }

    int m2 = m / 2;
    int sz = 1 << m2;
    for (int ma = 0; ma < sz; ma++) {
        bool _work = true;
        for (int i = 0; i < m2; i++) {
            if (!(ma & (1 << i))) continue;
            for (int j = 1; j < m2; j++) {
                if (!(ma & (1 << j))) continue;
                if (imp2[i][j]) {
                    _work = false;
                    break;
                }
            }
            if (!_work) break;
        }
        if (_work) cnt[ma]++;
    }
    for (int i = 0; i < m2; i++) {
        for (int ma = 0; ma < sz; ma++) {
            if (ma & (1 << i)) {
                cnt[ma] += cnt[ma ^ (1 << i)];
            }
        }
    }
    int m3 = m - m2;
    int sz3 = 1 << m3;
    long long ans = 0;
    for (int ma = 0; ma < sz3; ma++) {
        bool _work = true;
        int ma_l = (1 << m2) - 1;
        for (int i = 0; i < m3; i++) {
            if (!(ma & (1 << i))) continue;
            for (int j = 1; j < m3; j++) {
                if (!(ma & (1 << j))) continue;
                if (imp2[m2 + i][m2 + j]) {
                    _work = false;
                    break;
                }
            }
            if (!_work) break;
            for (int j = 0; j < m2; j++) {
                if (imp2[m2 + i][j]) ma_l &= ~(1 << j);
            }
        }
        ans += cnt[ma_l];
    }
    printf("%lld\n", ans);
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3820kb

input:

4
0 1 3 5

output:

5

result:

ok 1 number(s): "5"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3808kb

input:

5
0 1 2 3 4

output:

8

result:

ok 1 number(s): "8"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 3816kb

input:

49
1097363587067 1096810445814 275012137504 1096739142630 1096809921522 1087071335264 829364908576 949625500192 1087142638448 1096200190829 1097292808175 1095750860656 1087144145776 1097346808827 1095734082416 1096755396578 829230678048 1095663303524 1087072842592 1096216444777 949623992864 10962714...

output:

1148

result:

wrong answer 1st numbers differ - expected: '52', found: '1148'