傳送門
大力哈希亂搞。
每次操作產生的新的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());
}
}