压位暴力可过,甚至最优解第二
代码:
#include <stdio.h>
#include <string.h>
unsigned long long q[2048];
char op, bL, bR;
int L, R;
void range_set_0(int L, int R) {
if (L > R) return;
int qL = L >> 6, qR = R >> 6;
if (qL == qR) {
for (int i = L & 63; i <= R & 63; ++i) q[qL] &= ~(1ull << i);
return;
}
memset(q + qL + 1, 0x00, sizeof(unsigned long long) * (qR - qL - 1));
for (int i = L & 63; i < 64; ++i) q[qL] &= ~(1ull << i);
for (int i = R & 63; i >= 0; --i) q[qR] &= ~(1ull << i);
}
void range_set_1(int L, int R) {
if (L > R) return;
int qL = L >> 6, qR = R >> 6;
if (qL == qR) {
for (int i = L & 63; i <= R & 63; ++i) q[qL] |= 1ull << i;
return;
}
memset(q + qL + 1, 0xff, sizeof(unsigned long long) * (qR - qL - 1));
for (int i = L & 63; i < 64; ++i) q[qL] |= 1ull << i;
for (int i = R & 63; i >= 0; --i) q[qR] |= 1ull << i;
}
void range_rev(int L, int R) {
if (L > R) return;
int qL = L >> 6, qR = R >> 6;
if (qL == qR) {
for (int i = L & 63; i <= R & 63; ++i) q[qL] ^= 1ull << i;
return;
}
for (int i = qL + 1; i < qR; ++i) q[i] = ~q[i];
for (int i = L & 63; i < 64; ++i) q[qL] ^= 1ull << i;
for (int i = R & 63; i >= 0; --i) q[qR] ^= 1ull << i;
}
int main() {
while (~scanf(" %c %c%d,%d%c", &op, &bL, &L, &R, &bR)) {
L = (L << 1) + (bL == '(');
R = (R << 1) - (bR == ')');
if (L <= R)
switch (op) {
case 'U': range_set_1(L, R); break;
case 'D': range_set_0(L, R); break;
case 'C': range_rev(L, R); // Fallthrough
case 'I': range_set_0(0, L - 1); range_set_0(R + 1, 131070); break;
case 'S': range_rev(L, R); break;
}
else {
switch (op) {
case 'C':
case 'I': range_set_0(0, 131070); break;
}
}
}
bool found = false;
for (int i = 0, now_l = -1; i < 131072; ++i) {
if ((q[i >> 6] >> (i & 63)) & 1) {
if (now_l == -1) now_l = i;
} else if (now_l != -1) {
found = true;
printf("%c%d,%d%c ", now_l & 1 ? '(' : '[', now_l >> 1, i >> 1, i & 1 ? ']' : ')');
now_l = -1;
}
}
if (!found) printf("empty set");
return 0;
}