CCF 202009-3点亮数字人生 (100分)
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cassert>
using namespace std;
enum {
NOT,
AND,
OR,
XOR,
NAND,
NOR,
};
#define MAXM (2500+5)
#define MAXN 505
int M;
int N;
struct IO {
int in[MAXM];
int out[MAXN];
int len;
};
vector<IO> runs;
int Func(vector<int>& in, int op) {
int ans=in.front();
assert(ans != -1);
for (int i=1;i<in.size();++i) {
int x=in[i];
assert(x != -1);
switch (op) {
case AND:
case NAND:
ans &= x;
break;
case OR:
case NOR:
ans |= x;
break;
case XOR:
ans ^= x;
break;
}
}
switch (op) {
case NOT:
case NAND:
case NOR:
ans = !ans;
break;
}
return ans;
}
struct Node {
int func;
vector<int> in1;
vector<int> in2;
int out;
};
Node node[MAXN];
int inq[MAXN];
bool hasloop;
void DFS(int v) {
inq[v]=-1;
for (int i=0;i<node[v].in1.size();i++) {
int u=node[v].in1[i];
if (inq[u] == -1) {
hasloop=true;
} else if (!inq[u]) {
DFS(u);
}
}
inq[v]=1;
}
bool HasLoop() {
fill(inq+1, inq+N+1, 0);
hasloop=false;
for (int i=1;i<=N;++i) {
if (!inq[i]) {
DFS(i);
}
}
return hasloop;
}
void Compute(int root, int T) {
assert(inq[root]==0);
inq[root]=-1;
for (int i=0;i<node[root].in1.size();++i) {
int v=node[root].in1[i];
assert(inq[v] != -1);
if (!inq[v]) {
Compute(v, T);
}
}
vector<int> input;
for (int i=0;i<node[root].in1.size();++i) {
int v=node[root].in1[i];
input.push_back(node[v].out);
}
for (int i=0;i<node[root].in2.size();++i) {
int v=node[root].in2[i];
input.push_back(runs[T].in[v]);
}
int ans=Func(input, node[root].func);
node[root].out=ans;
inq[root]=1;
}
int Parse(char str[]) {
#define TRAN(x) if (!strcmp(#x, str)) return x;
TRAN(NOT)TRAN(AND)TRAN(OR)
TRAN(XOR)TRAN(NAND)TRAN(NOR)
#undef TRAN
return -1;
}
int main(int argc, char** argv) {
int Q;
scanf("%d", &Q);
while (Q--) {
scanf("%d%d", &M, &N);
for (int i=1;i<=N;++i) {
char str[25];
int k;
scanf("%s%d", str, &k);
int func=Parse(str);
node[i].func=func;
node[i].in1.clear();
node[i].in2.clear();
node[i].out=-1;
while (k--) {
scanf("%s", str);
int id=atoi(str+1);
if (str[0] == 'I') {
node[i].in2.push_back(id);
} else {
node[i].in1.push_back(id);
}
}
}
int S;
scanf("%d", &S);
runs.resize(S);
for (int i=0;i<S;++i) {
for (int j=1;j<=M;++j) {
int x;
scanf("%d", &x);
runs[i].in[j]=x;
}
}
for (int i=0;i<S;++i) {
int s;
scanf("%d", &s);
runs[i].len=s;
for (int j=0;j<s;++j) {
int id;
scanf("%d", &id);
runs[i].out[j]=id;
}
}
if (HasLoop()) {
puts("LOOP");
continue;
}
for (int i=0;i<S;++i) {
fill(inq+1, inq+N+1, 0);
for (int v=1;v<=N;++v) {
if (!inq[v]) {
Compute(v, i);
}
}
int len=runs[i].len;
for (int j=0;j<len;++j) {
int v=runs[i].out[j];
printf("%d%s", node[v].out, j==len-1?"\n":" ");
}
}
}
return 0;
}