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 ...
随机推荐
- 制作keil5的pack
[原创出品§转载请注明出处] 出处:http://www.cnblogs.com/libra13179/p/6273415.html 我在这里就交大家怎样制作自己的Pack,(这里是我制作好的http ...
- XE Styles不见了
C:\Users\Public\Documents\Embarcadero\Studio\15.0\Styles 我移动到D盘了 D:\Users\Public\Documents\Embarcade ...
- 浅谈实体类为什么要实现Serializable接口?
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创 ...
- Mongodb 安装 和 启动
教程:http://www.mongodb.org.cn/tutorial/59.html 下载 >wget https://fastdl.mongodb.org/linux/mongodb-l ...
- Hive 和 HBase区别
作者:yuan daisy 链接:https://www.zhihu.com/question/21677041/answer/78289309 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...
- Linux就业技术指导(七):游戏类运维重点流程解析
一,某游戏公司例行上线与更新流程示例 例行维护/更新流程 1.1 更新前天 提前确认好要更新的是什么,更新会有人通知你,一般是运营人员 比如:我们明天做什么什么更新 1.2 第2天更新 一般固定点更新 ...
- Python运维开发基础10-函数基础
一,函数的非固定参数 1.1 默认参数 在定义形参的时候,提前给形参赋一个固定的值. #代码演示: def test(x,y=2): #形参里有一个默认参数 print (x) print (y) t ...
- 清明梦超能力者黄YY(idx数组)
清明梦超能力者黄YY https://www.nowcoder.com/acm/contest/206/I 题目描述 黄YY是一个清明梦超能力者,同时也是一个记忆大师.他能够轻松控制自己在梦中的一切, ...
- Python并发讨论
手段有多线程,多进程,协程. 对于多线程: 由于GIL(全局解释器锁)的存在,多线程实际是单线程的,不能发挥多核的作用: 但对于IO密集型程序,多线程对于效率是有提高的,由于阻塞时,可能会切换到别的线 ...
- jQuery html5Validate基于HTML5表单验证插件
更新于2016-02-25 前面提到的新版目前线上已经可以访问: http://mp.gtimg.cn/old_mp/assets/js/common/ui/Validate.js demo体验狠狠地 ...