bzoj1932: [Shoi2007]Setstack 集合堆棧機

傳送門
大力哈希亂搞。
每次操作產生的新的set我們判斷之前有沒有出現過
每次大力插入就可以了。
至於判斷交集並集,我們大力使用stl中的函數
algorithm裏封裝了兩個函數是set_union和set_intersection,用於求集合的並和交。
用法是set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(x, x.begin())),set_intersection用法類似,這裏用了宏來簡化代碼。
然後就OK辣。
c++stl大法好

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define all(x) x.begin(),x.end()
#define ins(x) inserter(x,x.begin())
using namespace std;
typedef set<int> Set;
struct cmp{
    bool operator () (const Set &a,const Set &b){
        if (a.size()!=b.size()) return a.size()<b.size();
        Set::iterator ita=a.begin(),itb=b.begin();
        while (ita!=a.end()&&*ita==*itb) ++ita,++itb;
        if (ita==a.end()) return false;
        return *ita<*itb;
    }
};
char str[10];
int n;
stack<int> st;
map<Set,int,cmp> mp;
vector<Set> v;
int id(Set x){
    if (mp[x]!=0) return mp[x];
    v.push_back(x);
    return mp[x]=v.size()-1;
}
int main(){
    scanf("%d",&n);
    while (n--){
        scanf("%s",str);
        if (str[0]=='P') st.push(id(Set()));
        else if (str[0]=='D') st.push(st.top());
        else{
            Set x1=v[st.top()]; st.pop();
            Set x2=v[st.top()]; st.pop();
            Set x;
            if (str[0]=='U') set_union(all(x1),all(x2),ins(x));
            else if (str[0]=='I') set_intersection(all(x1),all(x2),ins(x)); 
            else x=x2,x.insert(id(x1));
            st.push(id(x));
        }
        printf("%d\n",v[st.top()].size());
    }
}
發佈了315 篇原創文章 · 獲贊 63 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章