QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#367591 | #7932. AND-OR closure | milmillin | WA | 1ms | 3820kb | C++14 | 3.0kb | 2024-03-26 09:12:01 | 2024-03-26 09:12:02 |
Judging History
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;
}
Details
Tip: Click on the bar to expand more detailed information
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'