Cod sursa(job #3207790)

Utilizator Luijika_programatorulBursuc Luigi Luijika_programatorul Data 26 februarie 2024 23:30:12
Problema Bool Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.36 kb
#include<bits/stdc++.h>
auto in = std::freopen("bool.in","r",stdin);
auto out = std::freopen("bool.out","w",stdout);
#define fast_io std::cin.tie(nullptr);std::cout.tie(nullptr);std::ios_base::sync_with_stdio(false);
std::vector<std::string> toks,toks_org;
std::vector<std::pair<int,int>> p;
bool cmp(std::pair<int,int> a, std::pair<int,int> b){
    return a.second - a.first < b.second - b.first;
}
int idx=0;
bool is_operator(std::string s){
    return s == "AND" || s == "OR" || s == "NOT" || s == "TRUE" || s == "FALSE";    
}
int prec(std::string str){
    if(str == "AND")return 2;
    return 1;
}
bool is_para(char c){return c == '(' || c == ')';}
bool is_opening(char c){return c == '(';}
bool is_closing(char c){return c == ')';}
bool is_value(std::string s){
    if(s[s.size()-1] == '!')s.pop_back();
    return !is_operator(s) && !is_para(s[0]);
}
bool is_not(std::string s){
    return s[s.size()-1] == '!';
}
int valz['Z'];
std::string S;
int n;
std::string vz;
std::string x;
void tokenize(){
    std::stringstream ss(S);
    while(ss >> x){
        int nr_para=0;
        while(x.size() && x[0] == '('){
            x.erase(x.begin());
            toks.push_back("(");
        }
        while(x.size() && x[x.size()-1] == ')'){
            x.pop_back();
            nr_para++;
        }
        
            if(x == "TRUE"){
                x = "1";
            }else if(x == "FALSE"){
                x = "0";
            }
            if(toks.size() && toks.back() == "NOT"){
                toks.pop_back();
                if(x == "1"){
                    toks.push_back("0");
                }else if(x == "0"){
                    toks.push_back("1");
                }else
                    toks.push_back(x + "!");
            }else{
                toks.push_back(x);
            }
        
        while(nr_para--){
            toks.push_back(")");
        }
    }
    toks_org = toks;
    std::stack<int> st;
    for(int i=0;i<toks.size() ; ++ i){
        if(is_opening(toks[i][0])){
            st.push(i);
        }else if(is_closing(toks[i][0])){
            p.push_back({st.top(),i});
            st.pop();
        }
    }
    std::sort(p.begin(),p.end(),cmp);

}

void solve_for(){
    std::set<std::pair<int,std::string>> s;
    for(int i=0;i<toks.size();++i){
        int xxor=0;
        if(toks[i] == "1"){
            s.insert({i,"1"});
        }else if(toks[i] == "0"){
            s.insert({i,"0"});
        }else if(is_value(toks[i])){
            int v = valz[toks[i][0]];
            if(is_not(toks[i])){
                v^=1;
            }
            s.insert({i,std::to_string(v)});
        }else{
            s.insert({i,toks[i]});
        }
    }

    for(auto f : p){
        //mai intai trebuie sa ma ocup de AND
        //dupa trebuie sa ma ocup de OR
        auto itst = ++s.lower_bound({f.first,""});
        auto itdr = s.lower_bound({f.second,""});
        std::stack<int> valz;
        while(itst != itdr){//acum ma ocup de AND
            if(itst->second == "AND"){
                auto st = std::stoi(((std::prev(itst))->second));
                auto dr = std::stoi(((std::next(itst))->second));
                std::string ss = std::to_string(st & dr);
                auto iitst = itst;iitst--;
                auto iitdr = itst;iitdr++,iitdr++;
                s.erase(iitst,iitdr);
                s.insert({itst->first,ss});
            }
            ++itst;
        }
        s.erase(s.lower_bound({f.first,""}));
        s.erase(s.lower_bound({f.second,""}));
        //acuma ma ocup de OR
        itst = ++s.lower_bound({f.first,""});
        itdr = s.lower_bound({f.second,""});
        while(itst != itdr){
             if(itst->second == "OR"){
                auto st = std::stoi(((std::prev(itst))->second));
                auto dr = std::stoi(((std::next(itst))->second));
                std::string ss = std::to_string(st | dr);
                auto iitst = itst;iitst--;
                auto iitdr = itst;iitdr++,iitdr++;
                s.erase(iitst,iitdr);
                s.insert({itst->first,ss});
            }
            ++itst;
        }   
        
    }
    std::stack<std::string> st;
    std::vector<std::string> yard;
    
    for(auto f : s){
        if(f.second.size() == 1){
            yard.push_back(f.second);
        }else{
            while(st.size() && prec(st.top()) < prec(f.second)){
                yard.push_back(st.top());
                st.pop();
            }
            st.push(f.second);
        }
    }
    while(st.size()){
        yard.push_back(st.top());
        st.pop();
    }
    std::stack<int> ans;
    for(int i=0;i<yard.size();++i){
        if(yard[i] == "AND" || yard[i] == "OR"){
            int first = ans.top();
            ans.pop();
            int second = ans.top();
            ans.pop();
            if(yard[i] == "AND"){
                second &= first;
            }else{
                second |=first;
            }
            ans.push(second);
        }else{
            ans.push(std::stoi(yard[i]));
        }
    }
    std::cout << ans.top();
}

int main(){
    fast_io
    getline(std::cin,S);
    tokenize();
    
    std::cin >> n;
    char ch;
    while(n--){
        std::cin >> ch;
        valz[ch] ^= 1;
        solve_for();
    }
    
    return 0;
}