解法:這題的官方作法是要我們直接一個 bit 一個 bit 去試,因為每個 bit 的運算都是獨立的,不受其他 bit 干擾,故總時間就是 $\mathcal O(2nm)$ 仍然在接受範圍內,但這個作法實在不是很聰明,而且 coding 起來頗有難度,換句話說我不知道要怎麼實作,於是我後來採取一個更巧妙的方式。我直接假設欲求未知數 “?” 的每個 bit 都是變數 x,那麼它的補數可表示為 1-x,在任何一個位元運算當中,無論運算元是常數還是變數,最後運算的結果都會是已知的 (deterministic),也就是說必定是 0、1、x、(1-x) 這四者裡面的其中一種,如此一來我們就可以針對這四者去設計一個「客製化」的運算規則,使得該位元最後的總和必為 ax + b 的形式,其中 a 是求得的整數係數、b 是非負常數。要讓 ax + b 最大,那 x 就必須在 $a>0$ 時為 1;要讓 ax + b 最小,那 x 就必須在 $a<0$ 時為 1;在 $a=0$ 的時候,根據題意,要讓 $x=0$。
#include<bits/stdc++.h>usingnamespacestd;intmain(){ios_base::sync_with_stdio(false);cin.tie(nullptr);// IO 優化
intn,m;cin>>n>>m;vector<short>coefficients;map<string,vector<char>>dict;for(inti=0;i<n;i++){stringa,b,c,d,e;cin>>a>>b>>c;assert(b==string(":="));if(c[0]=='0'||c[0]=='1'){for(intj=0;j<c.length();j++)dict[a].push_back((c[j]-'0')*0b11);// 0 => 0b00, 1 => 0b11
}else{cin>>d>>e;for(intj=0;j<m;j++){intopa=(c[0]=='?')?0b10:dict[c][j];// x ==> 0b10
intopb=(e[0]=='?')?0b10:dict[e][j];// x ==> 0b10
// we use 0b00 to denote 0, 0b01 to denote (1-x),
// 0b10 to denote x, 0b11 to denote 1.
if(d==string("AND"))dict[a].push_back(opa&opb);elseif(d==string("OR"))dict[a].push_back(opa|opb);elseif(d==string("XOR"))dict[a].push_back(opa^opb);elseassert(false);}}}for(intj=0;j<m;j++){intsum=0;for(auto&kv:dict){if(kv.second[j]==0b10)sum++;// number of x
if(kv.second[j]==0b01)sum--;// number of 1-x
}coefficients.push_back(sum);}for(intj=0;j<m;j++)cout<<1-(coefficients[j]>=0);cout<<'\n';for(intj=0;j<m;j++)cout<<(coefficients[j]>0);cout<<'\n';return0;}