[CSP-S 2023] 消消乐 & CF1223F 题解
我们称一个字符串是可消除的,当且仅当可以对这个字符串进行若干次操作,使之成为一个空字符串。其中每次操作可以从字符串中删除两个相邻的相同字符,操作后剩余字符串会拼接在一起。
You are trying to push array elements to the stack in the order \(s_1,s_2,s_3,…,s_l\). Moreover, if the stack is empty or the element at the top of this stack is not equal to the current element, then you just push the current element to the top of the stack. Otherwise, you don't push the current element to the stack and, moreover, pop the top element of the stack. If after this process the stack remains empty, the array s is considered stack exterminable.
空串合法
如果 \(A\) 合法,那么 \(xAx\) 合法
如果 \(A,B\) 合法,那么 \(AB\) 合法
题意是可以相互转化的。和括号匹配很像,区别是不分左右
sol 1
设 \(f[i]\) 表示以 \(i\) 结尾的合法子串数量,\(g[i]\) 为以 \(i\) 为右端点的最短合法子串的左端点,则 \(f[i]=f[g[i]-1]+1\)
剩下的问题是计算 \(g[i]\)。暴力:从 \(j=g[i-1]\) 开始不断跳 \(g[j]\) 至 \(s_{j-1}=s_{j}\),则 \(g[i]=j-1\)
考虑维护一个哈希表 \(h[j,x]\) 表示从 \(j\) 开始跳,最大的 \(j\) 满足 \(s_{j-1}=x\),则 \(g[i]=h[i-1,s_{i}]-1\)。\(h[i]\) 可以先从 \(h[g[i]]\) 继承过来,再令 \(h[i,s_{i-1}]=i\)
时间复杂度 \(O(n)\)
sol 2
结论:模拟 CF 题意,\([l,r]\) 合法 \(\iff[1,l-1]\) 和 \([1,r]\) 对应的栈相等
证明:如果 \([l,r]\) 中有字符和 \([1,l-1]\) 对应的栈中字符消了,那么由于 \([1,l-1]\) 和 \([1,r]\) 对应的栈相等,\([l,r]\) 中一定又有字符补上了,且顺序是对的
用哈希表维护 \([1,l-1]\) 对应的栈的哈希值即可统计答案
code
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx;
#define For(i,x,y,...) for(int i=x,##__VA_ARGS__;i<=(y);++i)
#define rFor(i,x,y,...) for(int i=x,##__VA_ARGS__;i>=(y);--i)
#define Rep(i,x,y,...) for(int i=x,##__VA_ARGS__;i<(y);++i)
#define pb emplace_back
#define sz(a) int((a).size())
#define all(a) begin(a),end(a)
#define fi first
#define se second
typedef long long LL; typedef vector<int> Vi; typedef pair<int,int> Pii;
auto ckmax=[](auto &x,auto y) { return x<y ? x=y,true : false; };
auto ckmin=[](auto &x,auto y) { return y<x ? x=y,true : false; };
sfmt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l,int r) { return uniform_int_distribution<>(l,r)(mt); }
template<typename T=int>T read() { T x; cin>>x; return x; }
typedef unsigned long long uLL;
const int N = 2e6+5;
int n,tp;
uLL pre[N],hsh[N];
char s[N],stk[N];
gp_hash_table<uLL,int> cnt;
signed main() {
#ifdef D
freopen("in","r",stdin); freopen("out","w",stdout);
#endif
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>s+1;
For(i,1,n) {
if( tp && stk[tp] == s[i] ) --tp;
else stk[++tp] = s[i], pre[tp] = pre[tp-1] * 131 + stk[tp];
hsh[i] = pre[tp];
}
LL ans = 0;
cnt[0] = 1; For(i,1,n) ans += cnt[hsh[i]], ++cnt[hsh[i]];
cout<<ans;
return 0;
}
sol 3
注意到消除满足“结合律”(先消哪里无所谓),不满足“交换律”(不能交换字符再消),可以(?)联想到矩阵乘法
引理:\(MM^{-1}=M^{-1}M=I\),其中 \(I\) 是单位矩阵
对于每种字符,随机一个矩阵 \(M\),下标为奇数对应 \(M\),下标为偶数对应 \(M^{-1}\)(下标奇偶性相同的两个字符之间有奇数个字符,这两个字符一定不能匹配)。\([l,r]\) 合法 \(\iff[l,r]\) 对应的矩阵乘积为 \(I\)
[CSP-S 2023] 消消乐 & CF1223F 题解的更多相关文章
- 消消乐、candy crush类三消游戏程序逻辑分析
最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...
- net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎
序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...
- [LeetCode] Candy Crush 糖果消消乐
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- RSP小组——消消乐
RSP小组--消消乐 团队所有博客总结 1.团队第一周作业 2.团队第二周作业 3.RSP小组--团队冲刺博客一 4.RSP小组--团队冲刺博客二 5.RSP小组--团队冲刺博客三 6.RSP小组-- ...
- PHP实现开心消消乐的算法示例
本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述: 1.在一个8*8的矩阵方格中随机 ...
- C#期末大作业 消消乐 2017-06-01 18:11 275人阅读 评论(0) 收藏
邻近期末,忙于刷题之余意识到期末大作业来不及了,匆匆赶下了作业,虽说做的很是粗糙,但完全原创的 下载链接 https://pan.baidu.com/s/1cCNLr4 大体的做大约3天完成了: 第一 ...
- Unity 3D游戏-消消乐(三消类)教程和源码
Unity 消消乐教程和源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Start Game -- ...
- 腾讯消消乐 (状态压缩DP)
腾讯消消乐 题意 给出长度为 n 的序列,每次可以选择删除序列的一个连续区间,要求这一段区间内所有数最大公约数不小于 k ,删除后剩下的序列仍然构成连续序列. 定义 f(i) 为进行 i 次操作将整个 ...
- ACM_开心消消乐
开心消消乐 Time Limit: 2000/1000ms (Java/Others) Problem Description: 大白最近喜欢上了开心消消乐,于是英语基础好的他准备让课文中英语句子也来 ...
- 热门游戏<开心消消乐>的“加壳”诡计!!
好久没搞游戏了,前几天看了又又一次看了看<开心消消乐>的1.29最新版..于是故事開始了: 1.反编译分析 首先使用Androidkiller进行反编译,得到两个Smali代码目录:mal ...
随机推荐
- Java的运行机制和JDK,JRE,JVM的区别
源文件(Java文件) > 编译器 > 字节码(class文件) > JVM(java虚拟机) > 操作系统 1.java首先利用文本编辑器写java源程序, ...
- 高通Android平台 电池 相关配置
背景 在新基线上移植有关的代码时,在log中发现有关的东西,请教了有关的同事以后,解决了这个问题. [ 12.775863] pmi632_charger: smblib_eval_chg_termi ...
- 关于ZYNQ-7000中断调试一点感想
背景 在ZYNQ 平台下,需要对各种需要的底层接口进行初始化. 我依次调试了很多驱动,从最简单的网口到USB:再到读写PL端的寄存器(通过AXI总线,内存映射读写物理地址实现),到中断的时候一直卡着不 ...
- .NET周刊【6月第4期 2024-06-23】
国内文章 C#.Net筑基-集合知识全解 https://www.cnblogs.com/anding/p/18229596 .Net中提供了数组.列表.字典等多种集合类型,分为泛型和非泛型集合.泛型 ...
- Power BI实用技巧:轻松打造专业级甘特图
Power BI实用技巧:轻松打造专业级甘特图 大家好,今天我们要一起探索Power BI中一个既实用又强大的功能--制作甘特图.甘特图以其直观展示项目时间线和任务进度的特点,在项目管理中扮演着重要角 ...
- VulnHub_DC-3渗透流程
VulnHub_DC-3 DC-3 是另一个特意建造的易受攻击的实验室,旨在获得渗透测试领域的经验. 与之前的 DC 版本一样,这个版本是为初学者设计的,尽管这一次只有一个flag.一个入口点并且根本 ...
- Java常见的加密方式
前言 传说在古罗马时代,发生了一次大战.正当敌方部队向罗马城推进时,古罗马皇帝凯撒向前线司令官发出了一封密信:VWRS WUDIILF.这封密信被敌方情报人员翻遍英文字典,也查不出这两个词的意思. 此 ...
- C# 判断字符串是否为整数
/// <summary> /// 判断一个字符串是否是正整数 /// </summary> /// <param name="s"></ ...
- 全网最适合入门的面向对象编程教程:02 类和对象的Python实现-使用Python创建类
全网最适合入门的面向对象编程教程:02 类和对象的 Python 实现-使用 Python 创建类 摘要 本文主要介绍了串口通信协议的基本概念.串口通信的基本流程.如何使用 Python 语言创建一个 ...
- 记一次 CDN 流量被盗刷经历
先说损失,被刷了 70 多RMB,还好止损相对即时了,亏得不算多,PCDN 真可恶啊. 600多G流量,100多万次请求. 怎么发现的 先是看到鱼皮大佬发了一篇推文突发,众多网站流量被盗刷!我特么也中 ...