本题主要考察 有向图是否存在环路,记忆化搜索,状态压缩存储。
#include <bits/stdc++.h>
//#include <iostream>
//#include <queue>
//#include <string>
using namespace std;
int Q, M, N, S;
using ll = long long;
// 状态压缩
ll input[10005][40];
short output[505];
bool hasloop;
struct node {
int op = 0; // 0 not, 1 and, 2 or, 3 xor, 4 nand, 5 nor
int from[7]; // 如果从器件得到是整数,如果是从 input 得到是负数
}elem[505];
int res[505]; // 运算结果, 如果结果未初始化是 0,初始化了是 1/-1
void mset(int t, int i) {
int index = i / 64;
int loc = i % 64;
input[t][index] |= (1 << loc);
}
int read(int t, int i) {
--i;
int index = i / 64;
int loc = i % 64;
return (input[t][index] >> loc) & 0x1;
}
bool vis[505];
void test() {
memset(vis, 0, sizeof(vis));
hasloop = false;
for (int i = 1; i <= N; ++i) {
if (vis[i]) continue;
queue<int> q;
q.push(i);
int mvis[505];
memset(mvis, 0, sizeof(mvis));
mvis[i] = true;
while(!q.empty()) {
int f = q.front(); q.pop();
for (int j = 0; j < 5; ++j) {
if (elem[f].from[j] == 0) break;
if (elem[f].from[j] > 0) {
int to = elem[f].from[j];
if (mvis[to]) {
hasloop = true;
return;
}
if (vis[to]) continue;
vis[to] = mvis[to] = true;
q.push(to);
}
}
}
}
}
int getRes(int no, int t) {
// cout << "no = " << no << ", op = " << elem[no].op << endl << "input: " << endl;
// for (int i = 0; i < 5; ++i) {
// cout << elem[no].from[i] << ", ";
// }
// cout << endl;
if (res[no] != 0) return res[no] == 1 ? 1 : 0;
int fv[5];
memset(fv, 0, sizeof(fv));
int cnt = 0;
for (int i = 0; i < 5; ++i) {
if (elem[no].from[i] == 0) break;
if (elem[no].from[i] < 0) {
fv[i] = read(t, -elem[no].from[i]);
} else {
fv[i] = getRes(elem[no].from[i], t);
}
cnt++;
}
int v = fv[0];
switch (elem[no].op) {
case 0:
v = !v; break;
case 1:
while (--cnt) {
v &= fv[cnt];
}
break;
case 2:
while (--cnt) {
v |= fv[cnt];
}
break;
case 3:
while (--cnt) {
v ^= fv[cnt];
}
break;
case 4:
while (--cnt) {
v &= fv[cnt];
}
v = !v;
break;
case 5:
while (--cnt) {
v |= fv[cnt];
}
v = !v;
break;
} // end switch
if (v == 0) res[no] = -1;
else res[no] = 1;
// cout << "no = " << no << ", res = " << res[no] << endl;
return v;
}
void solve() {
cin >> M >> N;
memset(elem, 0, sizeof(elem));
for (int i = 1; i <= N; ++i) {
string func;
int k;
string op;
cin >> func >> k;
if (func == "AND") elem[i].op = 1;
else if (func == "OR") elem[i].op = 2;
else if (func == "XOR") elem[i].op = 3;
else if (func == "NAND") elem[i].op = 4;
else if (func == "NOR") elem[i].op = 5;
for (int j = 0; j < k; ++j) {
cin >> op;
int t = atoi(op.substr(1).c_str());
if (op[0] == 'I') {
elem[i].from[j] = -t;
} else {
elem[i].from[j] = t;
}
}
}
// part 2
memset(input, 0, sizeof(input));
cin >> S;
for (int i = 0; i < S; ++i) {
int bit;
for (int j = 0; j < M; ++j) {
cin >> bit;
if (bit) {
mset(i, j);
}
}
}
// 测试是否有环
test();
if (hasloop) {
cout << "LOOP" << endl;
}
for (int t = 0; t < S; ++t) {
int s;
cin >> s;
for (int j = 0; j < s; ++j) {
cin >> output[j];
}
if (!hasloop) {
memset(res, 0, sizeof(res));
for (int j = 0; j < s; ++j) {
cout << getRes(output[j], t) << " ";
}
cout << endl;
}
// cout << "debug::" << endl;
// for (int k = 1; k <= N; ++k) {
// cout << getRes(k, t) << " ";
// }
// cout << endl << endl;
}
}
int main() {
cin >> Q;
while(Q--) solve();
return 0;
}