CSP 202303-3 LDAP

一开始是没有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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值