UVA12096 题解

2020-07-23 今日总结算法P1044栈P1449后缀表达式UVA514铁轨*UVA12096集合栈计算机 算法 P1044栈 卡特兰公式 组合数求解 #include<iostream> #include<algorithm> #include<stack> using namespace std; typedef long long int ll; ll a[36][36] = {0}; ll C(ll n,ll m) { //计算组合数 if (m == 0 阅读详情

这道题虽然被评黄,但个人感觉不止普及组难度,而且是一道很有价值的题目。题解区里全是 O(n2logn)O(n^2logn)O(n2logn) 的 STL 大法,我来发一篇 O(n2)O(n^2)O(n2) 哈希做法。目前 0ms 喜提最优解。

这道题是 codeforces gym 的题目,本质上就是模拟栈中集合插入,复制,相加,取交集,取并集的过程。注意,这些集合都是不可重集。 如果你直接把这些括号和逗号存下来肯定是不行的,因为它是一个一层套一层的结构,不好直接维护。况且经过复制,括号总数会指数级增长。

既然直接存储不行,我就想用哈希来表示每个集合里的元素。这样每个集合就是一个 vector,里面存储了每个元素对应的哈希值。比如集合 { { { } } , { { } , { } } } 的 vector 里存储 { { } } 和 { { } , { } } 这两个字符串的哈希。

下面考虑分别维护这五种操作。

  1. 对于 PUSH 操作,直接新建一个 vector,里面什么也不存推入栈中。

  2. 对于 DUP 操作,直接复制一遍栈顶的 vector 推入栈中。

  3. 对于 UNION 操作,我们需要把两个 vector 里的数全部放入新的 vector 内,并且去重。如果这两个 vector 无序,去重需要 O(nlogn)O(nlogn)O(nlogn) 的复杂度,是不能接受的。所以我们在维护 vector 里的哈希值时,不妨使其有序。 这样,在做 UNION 操作时,就可以归并排序去重了,复杂度 O(n)O(n)O(n) 。

  4. 对于 INTERSECT 操作,和 UNION 一样归并排序找到重复元素即可。

  5. 对于 Add 操作,这是最复杂的一个操作。记第一个 vector 为 v1v1v1,第二个 vector 为 v2v2v2。则我们要把 v1v1v1 这个整体作为一个元素,求出其哈希值并放入 v2v2v2。但注意:不能设计普通的按位乘法哈希。 至于为什么留给大家自己思考。(提示:括号总数巨大)

    虽然普通哈希不行,但我们有一个很好的性质,就是 v1 内的哈希值是有序的,唯一确定的。于是我们可以把哈希设计成这样:设 v1 内的哈希值为 h1h1h1,h2h2h2和h3h3h3,则有:

    H(v1)=((h1+Δ)×h2+Δ)×h3%PH(v1)=((h1+\Delta)\times h2+\Delta)\times h3\%PH(v1)=((h1+Δ)×h2+Δ)×h3%P

    其中 Δ\DeltaΔ 和 PPP 是自己设定的常数。注意计算哈希时还要在每个元素之间加一个逗号,左右两边加上大括号。然后把 H(v1)H(v1)H(v1) 用插入排序的方法移到 v2v2v2 相应位置。我这里使用了 vector 的 insert 函数,比插入排序快几十倍左右。

最后输出栈顶 vector 的大小即可。

代码:

#include<iostream>
#include<vector>
#include<algorithm>
#define f first 
#define s second
#define gc getchar
#define pc putchar
#define pb push_back
#define sz(a) a.size()
#define st(a) a.begin()
#define ed(a) a.end()
#define all(a) st(a),ed(a)
#define las(a) *a.rbegin()
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<class Typ> Typ &Rd(Typ &x){
    x=0; char ch=gc(),sgn=0;
    for(;ch<'0'||ch>'9';ch=gc()) sgn|=ch=='-';
    for(;ch>='0'&&ch<='9';ch=gc()) x=x*10+(ch^48);
    return sgn&&(x=-x),x;
}
template<class Typ> void Wt(Typ x){
    if(x<0) pc('-'),x=-x;
    if(x>9) Wt(x/10);
    pc(x%10^48);
}
const int N=2005;
const int Ad=1000099;
const int Md=998244353;
vector<int> Hs[N]; char op[10];
int cas,n,stk[N],top;
int main(){
    for(Rd(cas);cas;cas--){
        Rd(n),top=0;
        for(int i=1;i<=n;i++){
            Hs[i].clear(),scanf("%s",op+1);
            if(op[1]=='P') stk[++top]=i;
            else if(op[1]=='D'){
                for(auto j:Hs[stk[top]]) Hs[i].pb(j);
                stk[++top]=i;
            }else if(op[1]=='U'){
                int id1=stk[top--],id2=stk[top--],ps=0;
                for(auto cur:Hs[id1]){
                    for(;ps<sz(Hs[id2])&&Hs[id2][ps]<cur;ps++)
                        Hs[i].pb(Hs[id2][ps]);
                    Hs[i].pb(cur);
                    if(ps<sz(Hs[id2])&&Hs[id2][ps]==cur) ps++;
                }
                for(;ps<sz(Hs[id2]);ps++)
                    Hs[i].pb(Hs[id2][ps]);
                stk[++top]=i;
            }else if(op[1]=='I'){
                int id1=stk[top--],id2=stk[top--],ps=0;
                stk[++top]=i;
                for(auto cur:Hs[id1]){
                    while(ps<sz(Hs[id2])&&Hs[id2][ps]<cur) ps++;
                    if(ps<sz(Hs[id2])&&Hs[id2][ps]==cur) Hs[i].pb(cur);
                }
            }else{
                int Hsh=1+Ad,id1=stk[top--],id2=stk[top];
                for(auto cur:Hs[id1]){
                    if(Hsh!=1+Ad) Hsh=((ll)Hsh*2%Md+Ad)%Md;
                    Hsh=((ll)Hsh*cur%Md+Ad)%Md;
                }
                Hsh=((ll)Hsh*3%Md+Ad)%Md;
                if(!count(all(Hs[id2]),Hsh))
                    Hs[id2].insert(lower_bound(all(Hs[id2]),Hsh),Hsh);
            }
            Wt(sz(Hs[stk[top]])),pc('\n');
        }
        puts("***");
    }
    return 0;
}

写在最后:

要真的在联赛出这道题,我说不定就不选这种方法了,虽然保险,但 STL 也有优势,就是简单好写好调试。(而且 CCF 的数据不用多虑)不管怎么说,看到题解区同情 p 党,我也算是 python 的一员,哈希法也算是给 p 党一个可行的尝试方法了,只要把 vector 换成 list 即可。

做黄题让我回想起初一的时光,一去不复返了。也许有一天 OI 会从我脑中淡漠,但那段回忆永远藏着我的心中。

Codeforces D1/D2. Prefix-Suffix Palindrome (字符串hash) /详解 D1. Prefix-Suffix Palindrome (Easy version) D2. Prefix-Suffix Palindrome (Hard version) 题意: 对于给出的字符串,可截取其前缀和后缀,求能组成的最长回文串。 思路: 正常来说暴力的思路是先匹配前缀pre和后缀suf,找到第一个不匹配的l和r,然后在由l开始从左向右求最长的回文串palindrome,以及由r开始从右向左求最长的回文串palindrome,那么pre+palindrome+suf就是答案。 很显然,这是一个O(n^2)时间复杂度的算法,那么还有哪里可以优化呢?其实关于求回文串palindrom 立即下载

相关推荐

C语言编写Picard迭代和牛顿迭代法

为了完成学校计算方法的作业,花了两个多星期将所有实验报告编写出来,看到同桌找代码的辛苦,优快云也没有这类代码,我只是一时兴起,想分享我写的代码与大家共飨,有错误还请多多指正,代码都不难,也是为了让优快云帮我保存下,我辛辛苦苦做出来的,倘若能给别人带来一丝一毫的帮助,我都万分荣幸。 1:什么是Picard迭代 先弄一个满足f(x) = 0的函数将其转化为x= 正在上传… 重新上传 取消 ...

mohenxiang的博客 4699

C++如何手动开O2优化

C++手动开O2优化可以是编译器编译效率提高从而减少运行时间达到优化效果 #pragma GCC optimize(2)

cloudy_happy的博客 1942

Unity接入Google登录:Credential Manager完整集成指南与避坑实践

在移动应用开发中,第三方登录是提升用户体验和降低注册门槛的关键技术。其核心原理是通过OAuth 2.0等授权协议,安全地获取用户在平台的身份凭证。对于面向海外市场的Unity应用,Google登录因其庞大的用户基数成为首选方案。然而,随着Android系统更新和隐私政策收紧,传统的WebView登录方式面临兼容性挑战。Credential Manager作为Google推出的现代化凭据管理API,通过系统级集成解决了这一问题,它统一了密码、通行密钥和第三方登录的调用接口,显著提升了登录成功率和原生体验。在U

weixin_28025327的博客 318

字符串hash---CodeForces - 7D

http://codeforces.com/problemset/problem/7/D 题意:长度是 n 的字符串 s,如果它自身是回文数,且它的长度为 floor(n / 2)的前缀和后缀是 (k - 1)-回文数,则它被称作 k-回文数。按照定义,任何字符串 (甚至空字符串) 都是 0-回文数。 字符串 s 的回文度,被定义为这样的一个最大数 k,满足 s 是 k-回文数。...

小糊涂的博客 271

C语言由scanf(“%d“,)非法输入字符造成的死循环及其解决方案

声明:此文章仅作为C语言学习历程中的思路整理,用于解决入门阶段较为浅显的问题,如有错误还请指正。 现象描述: 代码要求实现用户输入1或2,通过scanf("%d",&a)读取这个值,从而判断分属于1或2的两种情况。输入非1,2的数字都应该返回"Invalid Number!",并且要求重新输入数字。 while(a!=1&&a!=2) { printf("Invalid Number!\n"); printf("Enter the number:"); scan

weixin_49764077的博客 8719

基于yolov5的鸟类图像准确识别

本项目主要基于yolov5进行鸟类准确识别,主要识别白鹭家族,红脚鹬,反嘴鹬,环颈珩,小白鹭以及夜鹭六类鸟

weixin_46064184的博客 3822

[究极好题][字符串哈希]Isomorphic Strings Codeforces985F

You are given a stringsof lengthnconsisting of lowercase English letters. For two given stringssandt, saySis the set of distinct characters ofsandTis the set of distinct characters oft. The stringssandtareisomorphicif their lengths are...

Cloth的博客 254

Unity实时控制佳能单反拍照全流程(附EDSDK 3.6.1配置避坑指南)

本文详细介绍了在Unity中实时控制佳能单反相机进行拍照的完整流程,重点提供了EDSDK 3.6.1的配置与避坑指南。内容涵盖从SDK获取、环境搭建、相机初始化、参数设置到实现拍照控制,并深入探讨了实时取景的延迟优化方案与资源管理,旨在帮助开发者高效集成专业相机,提升AR/VR及摄影测量等应用的视觉输入质量。

go5gopher的博客 184

字符串哈希+例题及其应用

想一下如果要比较/查询两个字符串并且这两个字符串规模很大,显然如果逐一比对字符串的字符效率就会很低,这个时候哈希就可以很快的解决这类问题,哈希就是将每一个字符串赋一个对应的数字值,这样比如说我们想看两个字符串是否相等,我们直接去看它对应的值是否相等即可,这样在预处理后我们就将每次的查询变成了O(1)!那么怎么得到这个对应的数字值呢?下面来看一下。

m0_73666576的博客 2152

别再手动转格式了!用Java+LibreOffice命令行实现Word批量转PDF(附Docker部署避坑指南)

本文详细介绍了如何利用Java和LibreOffice命令行实现企业级Word批量转PDF的自动化解决方案,包括多线程优化、Docker化部署及常见问题排查。通过代码示例和实战经验,帮助开发者高效处理文档转换需求,提升工作效率并避免常见陷阱。

552

【ARMv9 DSU-120 系列 1 -- DSU-120 DynamIQ 概述】

ARMv9架构中的DynamIQ™ Shared Unit-120(简称DSU-120)为一组基于Cortex-A类架构的核心提供了共享的L3内存系统、窥探控制(snoop control)和 过滤(filtering) 以及其他支持集群运作的控制逻辑。这个集群被称为DSU-120 DynamIQ™集群。此外,所有连接到片上系统(SoC)的外部接口也都是通过DSU-120提供的。一个DSU-120 DynamIQ™集群可以包含1到14个核心,且同一集群中可包含多达三种不同类型的核心。

CodingCos的博客 1185

CodeForces - 985F Isomorphic Strings(哈希)

题目链接:点击进入 题目 思路 代码 // Problem: Isomorphic Strings // Contest: Virtual Judge - CodeForces // URL: https://vjudge.net/problem/CodeForces-985F // Memory Limit: 262 MB // Time Limit: 3000 ms // // Powered by CP Editor (https://cpeditor.org) //#pragma GCC opt

Cosmic_Tree的博客 446

GEE训练教程:基于Sentinel-2卫星的归一化建筑指数(NDBI)等的进行城市扩张分析

本文介绍利用Sentinel-2卫星数据和谷歌地球引擎平台监测印度卡姆鲁普都会区2018-2024年城市扩张的方法。通过计算归一化建筑指数(NDBI)、植被指数(NDVI)和水体指数(MNDWI),采用多阈值规则识别建设用地,并量化不同年份的城市扩张面积。代码实现了从数据预处理、指数计算到面积统计的完整流程,为城市扩张研究提供了可复制的技术方案。关键参数包括年份选择、云覆盖阈值和分类阈值,均可根据研究需求调整。该方法能有效追踪城市边界变化,为城市规划提供数据支持。

此星光明博客 135

uva 12096 - The SetStack Computer(STL)

题目链接:uva 12096 - The SetStack Computer 题目大意:一个栈,有5种操作; PUSH:向栈中放一个空集合。DUP:复制栈顶集合。UNION:取栈顶的两个集合,取并集后放回。INTERSECT:取栈顶的两个集合,取交集后放回。ADD:取栈顶两个集合,将第一个集合作为元素放到第二个集合中,并将第二个集合放回栈。 每次操作后输出栈定集合中元素的个数。

不慌不忙、不急不躁 2353

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

UVA12096 集合栈计算机 The SetStack Computer

题目:https://www.luogu.org/problem/UVA12096 这个是各类集合的介绍:https://blog.youkuaiyun.com/KnightOnHourse/article/details/80106117 这个是插入迭代器的介绍:https://blog.youkuaiyun.com/m0_37456764/article/details/83019250 注意:inserter等迭代...

qq_37073764的博客 171

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

题解 The SetStack Computer(UVa12096)紫书P116STL的综合应用

先上Vjudge地址:点击这里 题目: 有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个开始为空的栈并且支持以下操作。 1.PUSH:空集“{}”入栈。 2.DUP:把当前栈顶元素复制一份后在入栈。 3.UNION:出栈两个集合,然后把二者的并集入栈。 4.INTERSECT:出栈两个集合,然后把二者的交集入栈。 5.ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。 例如,栈顶元素是A = { {},{{}} },下一个元素是B = { {}, {{{}}} },则:

Love_Jacques的博客 329

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

uva12096 - The SetStack Computer

STL+哈希

ACoder 312

习题5-5 UVA12096 The SetStack Computer(35行AC代码)

紫书刷题进行中,题解系列【GitHub|优快云】 习题5-5 UVA12096 The SetStack Computer(35行AC代码) 题目大意 用集合模拟计算机操作。每执行完一个操作,输出栈顶的集合大小,操作如下: PUSH:空集合压栈 DUP:将栈顶元素再次压栈 UNION:依次弹栈得a,b,求并集后压栈 INTERSECT:依次弹栈得a,b,求交集后压栈 ADD:依次弹栈得a,b,...

努力做个书呆儿 302

UVA 12096 The SetStack Computer STL

题目链接 UVA 12096: The SetStack Computer 题意 模拟一个存储元素为“集合”的栈操作,对应以下五个命令,分别有五种操作: PUSH:空集“{}”入栈 DUP:把当前栈顶元素复制一份后再入栈 UNION:出栈两个集合,然后把二者的并集入栈 INTERSECT:出栈两个集合,然后把二者的交集入栈 ADD:出栈两个集合,然后把先出栈的

Dmaxiya 468

UVA-12096 集合栈计算机 题解答案代码 算法竞赛入门经典第二版

GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 #include<string> #include<iostream> #include<set> #include<map> #include<vector> #include<stack> #include<algorithm> using namespace std; map<s

Coding home - 漂流瓶jz 317

【AcJoy群赛题解】 群赛01

比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=102313#overview 序号 原题 标题 FB 题解 备注 A   We Love MOE Girls 小王子     B   The Himalayas 小王子     C   Po

David_Jett 1364

算法竞赛入门经典(第2版)例题5-5 集合栈计算机 (The SetStack Computer UVa 12096)

这道例题书上的代码不全,我来补齐。 这章出现了n多新内容,紫书上一掠而过,我是不是该去读一读C++ primer plus? //#define LOCAL #include //使用set容器 #include//使用c++输入输出流 #include//使用map映射 #include//使用vector不定长数组 #include//使用stack栈 #include//使用

archya的专栏 1404

我的第一个:uva12096-解题思路

准确点讲,这道题不是我自己写出来,我先照着书上的代码敲了一遍,然后搞懂了思路: - 首先, 这道题最重要的是,应该想到:对每一个集合起一个特定的id,每一个集合应该是一个setint>,其中的int是为了存储该集合中的每一个集合的id. - 然后应该设置一个map,用来将每一个集合更它相对应的id结合起来,即mapint>, int>,再就是用一个vector把这些每一个大的包含其他元素

qq_27854685的博客 525

uva 12096 例题5-5 map vector set stack 混用

看了书上的做法,学习了多种容器如何一起使用。。一开始完全不适应多种容器感觉要晕了。。看了好久才大概理解了下,,将其代码复述了出来。。 思路其实就是讲每个集合对应一个唯一ID,之后有了这个ID就可以找到这个集合,从而可以找出这个集合里面有几个元素。这里也利用了集合的一个特点,就是里面元素都是没有重复的。也就是说如果将一个集合里面已经有的元素插入到集合中时,这个集合其实是没有改变的。。 主要学习的

liujc_的专栏 611

uva 12096 集合栈计算机

uva 12096 集合栈计算机 题目:有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且 支持以下操作。 PUSH:空集“{}”入栈。 DUP:把当前栈顶元素复制一份后再入栈。 UNION:出栈两个集合,然后把二者的并集入栈。 INTERSECT:出栈两个集合,然后把二者的交集入栈。 ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈...

qq_29904713的博客 283

UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)

UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)题意分析绝对的好题。 先说做完此题的收获: 1.对数据结构又有了宏观的上的认识; 2.熟悉了常用STL(set,map,vector)的常用用法; 3.学习了一种问题转化的方式。 我想如果告诉我这题用STL解决,并且还能独立完成的话,那么STL应该算是过关了。有下列操作集: 1.PUSH:向栈顶

Pengwill's Blog 460
上一篇: Ynoi2019模拟赛题解
-Autisia-
博客等级 码龄5年 1粉丝 3原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值