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; } }