The SetStack Computer UVA - 12096 set的合并操作相关
大小为n,m的set调用stl方法的复杂度是O(n+m),听说常数大(?)
这题的集合中,元素还是集合,
如果我们把每个集合都分配一个编号,那么就很容易用set表达出集合的包含关系
这个实现需要集合查找编码与编码查找集合
具体看代码吧
#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
#define ll long long
const int maxn=1e4+7;
const int inf=0x3f3f3f3f;
#define FOR(n) for(int i=1;i<=n;i++)
#define pb push_back
/******************************************************/
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
//fread->read
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if (p1==pend){
p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
if (pend==p1){IOerror=1;return -1;}
//{printf("IO error!\n");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
inline void read(int &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(ll &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=nc();blank(c);c=nc());
if (IOerror){c=-1;return;}
}
#undef OUT_SIZE
#undef BUF_SIZE
}; using namespace fastIO;
/*****************************************************/
typedef set<int> Set;
map<Set,int>IDcache; //集合映射为id;
vector<Set>Setcache; //根据id取集合
int ID(Set x){ //查找集合x的ID,找不到就分配新id
if(IDcache.count(x))return IDcache[x];
Setcache.pb(x);
return IDcache[x]=Setcache.size()-1;
}
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) //用于set_union系函数的首迭代器
int main(){
stack<int>s;
int n;cin>>n;
while(n--){
int m;cin>>m;
for(int i=0;i<m;i++){
string op;
cin>>op;
if(op[0]=='P')s.push(ID(Set()));
else if(op[0]=='D')s.push(s.top());
else{
Set x1=Setcache[s.top()];s.pop();
Set x2=Setcache[s.top()];s.pop();
Set x;
if(op[0]=='U')set_union(ALL(x1),ALL(x2),INS(x));
if(op[0]=='I')set_intersection(ALL(x1),ALL(x2),INS(x));
if(op[0]=='A'){x=x2;x.insert(ID(x1));}
s.push(ID(x));
}
cout<<Setcache[s.top()].size()<<endl;
}
cout<<"***"<<endl;
}
}
浙公网安备 33010602011771号