描述

中学数学里集合的元素往往是具体的数字,比如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)的更多相关文章

  1. BZOJ1932——[Shoi2007]Setstack 集合堆栈机

    1.题目大意:就是给你一个栈,有一些操作,向栈加入空集,把栈顶的元素复制一遍再加入栈,求栈顶两元素的并集,交集 还有栈的第一个元素和栈顶(将栈顶压缩成一个元素) 2.分析:这个其实不是用hash做的, ...

  2. BZOJ1932 [Shoi2007]Setstack 集合堆栈机

    妈呀...clj大爷太强啦! 原来还有set_union和set_intersection这种东西... 于是只要把栈顶的每个元素hash一下记录到一个vector里去就好了 /*********** ...

  3. 2018.08.28 ali 梯度下降法实现最小二乘

    - 要理解梯度下降和牛顿迭代法的区别 #include<stdio.h> // 1. 线性多维函数原型是 y = f(x1,x2,x3) = a * x1 + b * x2 + c * x ...

  4. 2018.08.28 洛谷P4556 [Vani有约会]雨天的尾巴(树上差分+线段树合并)

    传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...

  5. 2018.08.28 codeforces600E(dsu on tree)

    传送门 一道烂大街的dsu on tree板题. 感觉挺有趣的^_^ 代码真心简单啊! 就是先处理轻儿子,然后处理重儿子,其中处理轻儿子后需要手动消除影响. 代码: #include<bits/ ...

  6. 2018.08.28 洛谷P3803 【模板】多项式乘法(FFT)

    传送门 fft模板题. 终于学会fft了. 这个方法真是神奇! 经过试验发现手写的complex快得多啊! 代码: #include<iostream> #include<cstdi ...

  7. 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)

    传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...

  8. 2018.08.28 洛谷P3345 [ZJOI2015]幻想乡战略游戏(点分树)

    传送门 题目就是要求维护带权重心. 因此破题的关键点自然就是带权重心的性质. 这时发现直接找带权重心是O(n)的,考虑优化方案. 发现点分树的树高是logn级别的,并且对于以u为根的树,带权重心要么就 ...

  9. JZOJ5804. 【2018.08.12提高A组模拟】简单的序列

    性质:每个位置的前缀和必须大于0,总和=0.以此dp即可. #include <iostream> #include <cstdio> #include <cstring ...

随机推荐

  1. Laravel基础

    一.Laravel核心目录文件介绍 app:程序的核心代码和业务逻辑代码,其中的Http目录是我们业务逻辑的存放点 bootstrap:包含框架启动的和自动加载文件 config:包含所有程序中的配置 ...

  2. 队列queue实例(生产者和消费者模型)

    import queue, threading, time q = queue.Queue(maxsize=10)def producter(n): count = 1 while True: q.p ...

  3. vue基础——表单输入绑定

    一.基础用法 你可以用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定.它会根据控件类型自动选择正确的方法来更新元素. 尽管有些神 ...

  4. Technology, globalisation and the squeeze on good jobs

    Technology, globalisation and the squeeze on good jobs技术与全球化冲击好工作“Highest stock market EVER! Jobs ar ...

  5. Haskell语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...

  6. mysql 存储过程分页 转载

    /* --名称:MYSQL版查询分页存储过程 by peace 2013-8-14 --输入参数:@fields -- 要查询的字段用逗号隔开 --输入参数:@tables -- 要查询的表 --输入 ...

  7. C++ 0x 使用可变参数模板类 实现 C# 的委托机制

    #ifndef _ZTC_DELEGATE_H_ #define _ZTC_DELEGATE_H_ #include <vector> #include <functional> ...

  8. 处理【由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面】

    处理[由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面] 详细错误:HTTP 错误 404.2 - Not Found. 由于 Web 服务器上的“ISAPI 和 ...

  9. RabbitMQ 高可用集群搭建

    面向EDA(事件驱动架构)的方式来设计你的消息 AMQP routing key的设计 RabbitMQ cluster搭建 Mirror queue policy设置 两个不错的RabbitMQ p ...

  10. HTTP协议图示详解

    一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器. ...