2018.08.28 集合堆栈机(模拟+STL)
描述
中学数学里集合的元素往往是具体的数字,比如A = {1,2,3},B = {}(空集)等等。但是要特别注意,集合的元素也可以是另一个集合,比如说C = {{}},即说明C有且仅有一个元素——空集B,所以称B是C的子集或者称B是C的元素都是正确的。所谓一个集合的势,就是这个集合的元素个数,一般记为|S|,空集的势为0。在上例中,|A| = 3,|B| = 0,|C| = 1。 鉴于集合论是现代数学的基础理论这一事实,一群异想天开的科学家开始着手建造一台新式的超级计算机——集合堆栈机Alpha,这台机器操作的将是集合而不是数字。不过由于Alpha的竣工之日遥遥无期,科学家们希望你为他们编写一台虚拟机,好让他们检查自己的原型设计是否合理。 Alpha的存储设备只有一个栈,栈的每个单元都只能放置一个集合。一开始,栈是空的,在每个操作结束后,计算机就会输出位于栈顶单元的那个集合的势。Alpha拥有五种不同的指令,分别为:PUSH、DUP、UNION、INTERSECT和ADD,他们的功能如下:
PUSH: 把一个空集{}压入栈;
DUP: 取出位于栈顶单元的集合,复制一遍以后再把两个同样的集合压入栈;
UNION: 取出位于栈顶单元的前两个集合,然后把它们的并集压入栈;
INTERSECT: 取出位于栈顶单元的前两个集合,然后把它们的交集压入栈;
ADD: 取出位于栈顶单元的前两个集合,首先取出的记为S,其次取出的记为T,最后把T∪{S}压入栈;
图为例,可见位于虚拟机堆栈顶端的两个元素是:
A = { {}, {{}} }
B = { {}, {{{}}} }
根据势的定义,我们有|A| = 2 以及 |B| = 2。接下来,
如果选择UNION操作,结果是{{},{{}},{{{}}},输出3
如果选择INTERSECT操作,结果是{{}},输出1
如果选择ADD操作,结果是{{},{{{}}},{{},{{}}}},输出3
分别执行三条指令之后虚拟机就会变成以下三种样子:
输入
文件的第一行只有一个整数n(0≤n≤2000),代表将要执行的指令条数。接下来有n行,每行有包含一条大写的指令,我们保证每条指令都是上述五条指令中的一条,并且虚拟机总是能正确执行完所有的指令。
输出
输出虚拟机的输出结果即可。每行输出一个大于或等于0的整数,代表虚拟机执行该条指令后的输出。选手们务必仔细考量程序的执行效率。
样例输入
9
PUSH
DUP
ADD
PUSH
ADD
DUP
ADD
DUP
UNION
样例2
5
PUSH
PUSH
ADD
PUSH
INTERSECT
样例输出
0
0
1
0
1
1
2
2
2
样例2
0
0
1
0
0
标签
shoi2007
康复训练ing。。。
好吧这题显然不能直接模拟,有一种感觉很优秀的做法是将集合映射成int来乱搞。
然后写了一发感觉取交集与并集有点麻烦。。。
赶快百度了一波惊奇的发现STL中已经有了这个操作心情大好!
于是顺利跑过了。
代码:
#include<bits/stdc++.h>
using namespace std;
struct cmp{
inline bool operator()(const set<int>&a,const set<int>b){
if(a.size()!=b.size())return a.size()<b.size();
set<int>::iterator ita=a.begin(),itb=b.begin();
while(ita!=a.end()&&*ita==*itb)++ita,++itb;
return ita==a.end()?false:(*ita<*itb);
}
};
stack<int>stk;
map<set<int>,int,cmp>mp;
vector<set<int> >vec;
inline int findid(set<int>x){
if(mp[x])return mp[x];
vec.push_back(x);
return mp[x]=vec.size()-1;
}
int main(){
string s;
int q;
scanf("%d",&q);
while(q--){
cin>>s;
if(s[0]=='P')stk.push(findid(set<int>()));
else if(s[0]=='D')stk.push(stk.top());
else{
set<int>x1=vec[stk.top()],tmp;
stk.pop();
set<int>x2=vec[stk.top()];
stk.pop();
if(s[0]=='U')set_union(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(tmp,tmp.begin()));
else if(s[0]=='I')set_intersection(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(tmp,tmp.begin()));
else tmp=x2,tmp.insert(findid(x1));
stk.push(findid(tmp));
}
cout<<vec[stk.top()].size()<<'\n';
}
return 0;
}
2018.08.28 集合堆栈机(模拟+STL)的更多相关文章
- BZOJ1932——[Shoi2007]Setstack 集合堆栈机
1.题目大意:就是给你一个栈,有一些操作,向栈加入空集,把栈顶的元素复制一遍再加入栈,求栈顶两元素的并集,交集 还有栈的第一个元素和栈顶(将栈顶压缩成一个元素) 2.分析:这个其实不是用hash做的, ...
- BZOJ1932 [Shoi2007]Setstack 集合堆栈机
妈呀...clj大爷太强啦! 原来还有set_union和set_intersection这种东西... 于是只要把栈顶的每个元素hash一下记录到一个vector里去就好了 /*********** ...
- 2018.08.28 ali 梯度下降法实现最小二乘
- 要理解梯度下降和牛顿迭代法的区别 #include<stdio.h> // 1. 线性多维函数原型是 y = f(x1,x2,x3) = a * x1 + b * x2 + c * x ...
- 2018.08.28 洛谷P4556 [Vani有约会]雨天的尾巴(树上差分+线段树合并)
传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...
- 2018.08.28 codeforces600E(dsu on tree)
传送门 一道烂大街的dsu on tree板题. 感觉挺有趣的^_^ 代码真心简单啊! 就是先处理轻儿子,然后处理重儿子,其中处理轻儿子后需要手动消除影响. 代码: #include<bits/ ...
- 2018.08.28 洛谷P3803 【模板】多项式乘法(FFT)
传送门 fft模板题. 终于学会fft了. 这个方法真是神奇! 经过试验发现手写的complex快得多啊! 代码: #include<iostream> #include<cstdi ...
- 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)
传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...
- 2018.08.28 洛谷P3345 [ZJOI2015]幻想乡战略游戏(点分树)
传送门 题目就是要求维护带权重心. 因此破题的关键点自然就是带权重心的性质. 这时发现直接找带权重心是O(n)的,考虑优化方案. 发现点分树的树高是logn级别的,并且对于以u为根的树,带权重心要么就 ...
- JZOJ5804. 【2018.08.12提高A组模拟】简单的序列
性质:每个位置的前缀和必须大于0,总和=0.以此dp即可. #include <iostream> #include <cstdio> #include <cstring ...
随机推荐
- 前段开发-css-总结
应用参考https://www.cnblogs.com/alice-bj/p/8972299.html CSS:层叠样式表(Cascading Style Sheets) 1.css的特征 一.css ...
- Java LinkList遍历方式
1.LinkedList的遍历方式 a.一般的for循环(随机访问) int size = list.size(); for (int i=0; i<size; i++) { list.get( ...
- ArcGIS 复制要素
DataManagementTools.General.Copy DataManagementTools.Features.CopyFeatures ConversionTools.ToGeodata ...
- WinForm多线程编程与Control.Invoke的应用浅谈
在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来.一个最直接的方法便是使用多线程.多线程编程的方式在WinForm开发中必不可 ...
- 吴裕雄 实战PYTHON编程(5)
text = '中华'print(type(text))#<class 'str'>text1 = text.encode('gbk')print(type(text1))#<cla ...
- 问题解决Android studio遇到 java.lang.OutOfMemoryError: GC app:transformClassesWithDexForDebug解决方法 以及gradle优化
http://blog.csdn.net/xiaoxing0828/article/details/52242090
- HTTP 和 Socket 区别
要弄明白 http 和 socket 首先要熟悉网络七层:物 数 网 传 会 表 应,如图1 如图1 HTTP 协议:超文本传输协议,对应于应用层,用于如何封装数据. TCP/UDP 协议:传输控制协 ...
- seleniumIDE的实践
浏览器:1.Firefox setup35.0.12.安装完成后设置菜单栏---安装完浏览器,鼠标定位在浏览器的状态栏,然后点击鼠标右键,点击勾选菜单栏,这时候就有菜单栏出现了 3.关闭浏览器自动更新 ...
- 如何使用eclipse搭建maven环境以及常见的错误
这篇博客适合零基础学习maven,搭建maven以及运行项目,常见的错误,我会在结尾写出说明白,看是否和大家的错误一样,或者文章的括号注释部分也会写出一些注意点. 第一步:就是下载maven,以及配置 ...
- discrete
discrete - 必应词典 美[dɪ'skrit]英[dɪ'skriːt] adj.离散的:分离的:各别的 网络不连续的:分立的:离散型