一开始是没有attrUsers这个map的,于是在retBasicExprSet函数中如果是”:"就要遍历整个mapper,这会比较费时,于是就t了,加了这个小优化就可以过了,但是还是用时比较长。
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,map<int,set<int>>>mapper;
unordered_map<int,set<int>> attrUsers;
int n,m;
set<int> retBasicExprSet(const string& exp) {
int p = 0;set<int> ans;
while(exp[p] != ':' && exp[p] != '~') p++;
int a = atoi(exp.substr(0,p).c_str());
int b = atoi(exp.substr(p+1, exp.size()).c_str());
if(exp[p] == ':') {
ans.insert(mapper[a][b].begin(), mapper[a][b].end());
}
else {
ans.insert(attrUsers[a].begin(), attrUsers[a].end());
set<int> dead;
for(auto it : mapper[a][b]) {
if(ans.count(it)) {
dead.insert(it);
}
}
for(auto it : dead) ans.erase(it);
}
return ans;
}
set<int> retComplexExprSet(const string& str) {
stack<int>stk;
char firChar = str[0];
if(firChar != '&' && firChar != '|') return retBasicExprSet(str);
set<int> ret;
int lasPos = 2;
bool upd = false;
for(int i = 1; i < str.size(); i++) {
if(str[i] == '(') stk.push('(');
if(str[i] == ')') stk.pop();
if(stk.empty()) {
set<int> st = retComplexExprSet(str.substr(lasPos,i - lasPos));
lasPos = i + 2;
if(!upd) {
upd = true; ret = st;
continue;
}
upd = true;
if(firChar == '&') {
set<int>tmp;
for(auto& val:st) {
if(ret.count(val)) tmp.insert(val);
}
ret = tmp;
} else {
ret.insert(st.begin(), st.end());
}
}
}
return ret;
}
void solve(const string& str) {
set<int> res = retComplexExprSet(str);
for(auto dn: res) {
cout << dn << ' ';
}
cout << '\n';
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) {
int DN; cin >> DN;
int totNum; cin >> totNum;
for(int j = 1; j <= totNum; j++) {
int k,v; cin >> k >> v;
mapper[k][v].insert(DN);
attrUsers[k].insert(DN);
}
}
cin >> m;
for(int i = 1; i <= m; i++) {
string str;
cin >> str;
solve(str);
}
}