最多仅仅只有一个位为x,其余的位均为0或者1。首先计算出全0以及全1的输入所对应的输出,如果二者是相等的,说明输出其实就是一个常数,那么我们就直接将输入指定为全0就可以了。如果二者不是相等的,那么就可以考虑全0的输入所对应的输出以及全1的输入所对应的输出二者之间的转化,只要从某一个想另外的一个转化就行了,这里使用的是从全1向全0的方向,逐步增加0的个数,如果增加到某一位能够成功转换,那么说明输入其实是由这一位决定的,那么就将这一位指定为x,这一位之前均为0,之后均为1即可,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
const int maxn = 200000 + 5;
typedef struct node{
int a, b;
int o;
}node;
node gate[maxn];
int getRes(int k,int m){//代表前面有k个0
for (int i = 1; i <= m; i++){
int a = gate[i].a;
int b = gate[i].b;
int oa = a<0 ? (-a)>k:gate[a].o;
int ob = b<0 ? (-b)>k:gate[b].o;
gate[i].o = !(oa&&ob);
}
return gate[m].o;
}
int Deal(int aim,int n,int m){
int L = 1, R = n;
while (L < R){
int mid = L + (R - L) / 2;
int res = getRes(mid, m);
if (res == aim) R = mid;
else L = mid + 1;
}
return L;
}
int main(){//下标从1开始
int d;
cin >> d;
while (d--){
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++){
cin >> gate[i].a >> gate[i].b;
}
int v0 = getRes(0,m);//全1
int vn = getRes(n,m);//全0
if (v0 == vn){
for (int i = 1; i <= n;i++) cout << "0";
}
else{
int ind = Deal(vn, n, m);
for (int i = 1; i < ind; i++) cout << "0";
cout << "x";
for (int i = ind + 1; i <= n; i++) cout << "1";
}
cout << endl;
}
return 0;
}