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 ...
随机推荐
- shell echo 打印换行
echo -e "aaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbb"
- MySQL 获取最后插入的ID LAST_INSERT_ID用法
LAST_INSERT_ID() 自动返回最后一个INSERT或 UPDATE 查询中 AUTO_INCREMENT列设置的第一个表发生的值. MySQL的LAST_INSERT_ID的注意事项: 第 ...
- as3 文档类引用
/**文档类引用**/ public static var main:CoverMain; public function CoverMain() { main=this; }
- eclipse从svn导入maven项目变成普通项目解决办法
右击项目-->configure-->Convert to Maven Project
- Haskell语言学习笔记(60)Biapplicative
Biapplicative class Bifunctor p => Biapplicative p where bipure :: a -> b -> p a b (<< ...
- 批量导入数据(Mysql)报MySQL server has gone away 问题的解决方法
问题分析 首先度娘:mysql出现ERROR : (2006, 'MySQL server has gone away') 的问题意思就是指client和MySQL server之间的链接断开了. 造 ...
- maven 的聚合
- linux下字符串的比较方式
A="$1" B="$2" #判断字符串是否相等 if [ "$A" = "$B" ];then echo &qu ...
- Bean Validation技术实现对Javabean的校验
概述:在java开发时,由于分层的原因(表现层-控制层-业务层-数据持久层),有时候需要对传入的Javabean进行校验,如果过多的校验会导致比较繁琐,做重复的工作,下面将介绍Bean Validat ...
- 安装64位的oracle数据库, 使用自带的sqldeveloper
个人感觉这个东西比plsql要好用, 虽然界面有点丑, 整个使用与plsql也没多大区别, 这里是他的位置C:\oracle_11g\product\11.2.0\dbhome_1\sqldevelo ...