P4965 薇尔莉特的打字机
题目
快到十二点了正在颓废突然发现了一道好题
虽然毒瘤,但确实是容斥原理的好题啊,做法也特别巧妙(标程
思路
题目大意(怕自己突然忘)
n个初始字符,m个操作(加入或删除),任何一个操作都可能无效,求最后不同的字符方案数\((n,m<=5*10^6)\)
先考虑无删除操作
这里的\(t_{0..i}\)为一个字串,\(\widetilde{t_{0..i}}\)指该字串不同的子序列个数,\(dp_i\)为\(\widetilde{t_{0..i-1}}\)
若\(t_{i}\)这个字符在循环时第一次出现,即\(t_{0...i-1}\)没出现过\(t_{i}\),显然我们考虑的状态有三种
\(~~~~~1.\widetilde{t_{0..i-1}}\),有 \(dp_{i-1}\)个\(\Longrightarrow\)理解:插入操作无效或只考虑前面字符的方案数
\(~~~~~2.\widetilde{t_{0..i-1}} + \{t_i\}\),有\(dp_{i-1}\)个\(\Longrightarrow\)理解:插入操作有效,且与前面字符组合起来的方案数
\(~~~~~3.\widetilde{t_{i..i}}\)\(\Longrightarrow\)理解:插入操作有效\(t_{i}\)单独组成一种方案
综上,\(t_{i}\)这个字符在循环时第一次出现:\(dp_{i}=2*dp{i-1}+1\)
\(\begin{aligned}
\\
\end{aligned}\)
那不是第一次出现呢?显然会出现重复的子序列
\(lst[c]\)表示字符\(c\) 上一次出现的位置
1.\(\widetilde{t_{0..lst[t_i]-1}}+\{t_{lst[t_i]}\}\)与\(\widetilde{t_{0..lst[t_i]-1}}+\{t_i\}\) 重复
2.\(\{t_{lst[t_i]}\}\) 与 \(\{t_i\}\) 重复
综上,\(dp_i\)要去掉\(dp_{lst[t_i]-1}+1\)
\(\therefore dp_i=\begin{cases}2*dp_{i-1}+1\quad(t_i\text{第一次出现})\\2dp_{i-1}-dp_{lst[t_i]-1}\quad (t_i\text{出现过})\end{cases}\)
目前为止,时间复杂度为\(O(m)\),毒瘤的出题人不可能就这样放过我们嘛\(emmm\)
考虑删除操作
其实删除操作只用考虑删除前面的文本串,为什么?删除插入操作无异与:删除与插入两个操作同时无效,而前面的方程已经将此情况考虑进去了
故我们只用考虑文本串与插入操作中间的删除操作
当能作为有效删除操作为\(cnt\)个时,我们枚举有\(k(k<=cnt)\)个有效操作
则此时新增子序列\(s_{0..n-k-1} + \widetilde{t_{pre[p_k]..m-1}}\)

发现没有?从小到大枚举\(k\),时间复杂度瞬间指数加\(1\)成了\(O(m^2)\),那我们就从\(m-1\)~\(0\)逆推,又变成线性的了!!
故\(dp_i\)为\(\widetilde{t_{i..m-1}}\),\(lst[c]\)为倒推时字符\(c\)上一次出现的位置,由于删除操作的存在,方程中的\(dp_{i-1}\) 改为\(dp_{pre[i]}\)(这些应该都好理解吧)
\(\begin{aligned}
\\
\end{aligned}\)
同样地,我们还得考虑重复部分,
若退格所删去的最后一个字符即\(s_{n-k}\)在 \(t_{pre[p_k]..m-1}\) 中出现过,则会产生重复的答案:第\(k\)删除在文本串\(s\)中删除的字符是\(s_{n-k}\),
而在第\(k-1\) 个删除 时,\(s_{n-k}\)不会被删除,则一旦 \(s_{n-k}\) 在 \(t_{pre[p_k]..m-1}\) 中出现过,就意味着在只有\(k-1\)个删除时\(s_{n-k}\)会与后面的发生重复
重复子序列为\(s_{0..n-k}+\widetilde{t_{pre[lst[s_{n-k}]]..m-1}}\)以及\(s_{0..n-k}\),个数为 \(dp_{pre[lst[s_{n-k}]]}+1\),计算答案时要将这部分减去

My complete code
上短得可怜的代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int p=0x125E591;
const int maxn=5000000+9;
int n,m,pos,cnt,ans;
int lst[maxn],pre[maxn],dp[maxn];
char s[maxn],t[maxn];
inline int Get(char x){
return (lst[x])?p-dp[pre[lst[x]]]:1;
}
int main(){
scanf("%d%d",&n,&m);
scanf(" %s %s",s,t);
for(int i=0;i<m;++i)
cnt+=(t[i]=='u');
for(int i=m-1;i>=0;--i)
if(t[i]=='u'){
if(n-cnt>=0)
ans=(ans+dp[pos]+Get(s[n-cnt]))%p;
--cnt;
}else{
dp[i]=(2*dp[pre[i]=pos]+Get(t[i]))%p;
pos=lst[t[i]]=i;
}
printf("%d",(ans+dp[pos]+1)%p);
return 0;
}
总结
动规啊容斥啊这些真的得完全弄懂再去写代码,几次想写代码了还是回过头自己纯手推了一下
能想到写篇博客竟然花了快一个多小时,凌晨一点半 其实也还早啊,睡觉
P4965 薇尔莉特的打字机的更多相关文章
- 洛谷4965 薇尔莉特的打字机(Trie,DP)
神仙题. 考虑在一棵 Trie 上进行染色,将可能出现的串的末尾染成黑色.答案就是黑点的个数.一开始只有 \(A\) 的末尾点是黑色. 当出现一个字符(不是退格)\(c\) 时,就要将每个黑点的 \( ...
- ACM训练联盟周赛(第一场)
B:Zeratul与Xor 题目描述 Xor(按位异或),对应C++中的“^”运算符. Zeratul给出了一个数列A[n](n≤105),要做q(q≤105)组动作,这些动作包括: 1 a:数列中 ...
- 【胡策篇】题解 (UOJ 192 + CF938G + SPOJ DIVCNT2)
和泉纱雾与烟花大会 题目来源: UOJ 192 最强跳蚤 (只改了数据范围) 官方题解: 在这里哦~(说的很详细了 我都没啥好说的了) 题目大意: 求树上各边权乘积是完全平方数的路径数量. 这种从\( ...
- Python语言之面向对象
Python语言之面向对象 前言 面向对象 -- Object Oriented 简写:OO 面向对象设计 -- Object Oriented Design 简写:OOD 面向对象编程 -- Obj ...
- 小贝_mysql select连接查询
select连接查询 简要: 一.union联合查询 二.左右内连接 一.union联合查询 作用: 把2次或多次查询结果合并起来 具体: (表1查询结果) union (表2查询结果) 运行: 先算 ...
- 营口6378.7939(薇)xiaojie:营口哪里有xiaomei
营口哪里有小姐服务大保健[微信:6378.7939倩儿小妹[营口叫小姐服务√o服务微信:6378.7939倩儿小妹[营口叫小姐服务][十微信:6378.7939倩儿小妹][营口叫小姐包夜服务][十微信 ...
- 本溪6397.7539(薇)xiaojie:本溪哪里有xiaomei
本溪哪里有小姐服务大保健[微信:6397.7539倩儿小妹[本溪叫小姐服务√o服务微信:6397.7539倩儿小妹[本溪叫小姐服务][十微信:6397.7539倩儿小妹][本溪叫小姐包夜服务][十微信 ...
- FreeBSD基金会添加新成员,梁莉成为第一位来自微软和中国的基金会董事
这个月23日FreeBSD基金会很高兴地宣布Philip Paeps和Kylie Liang (梁莉)正式加入董事会. 梁莉,现任微软开源技术部高级项目经理,主要负责FreeBSD在公有云以及私有云的 ...
- 【爆料】-《英博夏尔大学毕业证书》BPP一模一样原件
英博夏尔大学毕业证[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&a ...
随机推荐
- asp.net core mvc视频A:笔记1.基本概念介绍
此笔记来自视频教程 MVC本身与三层架构没有联系 使用VS2017新建一个默认的asp.net core mvc网站,认识结构及文件用途.
- mysql忘记root密码解决
修改配置文件:my.cnf 加上skip-grant-tables 重启mysql mysql -uroot 登录 mysql> USE mysql ; mysql> UPDATE u ...
- CDN对于动态加速是否有效
CDN对于动态加速是否有效的问题.关于这个问题,一直存在一些分歧,部分人认为有效,部分人认为无效,主要是CDN技术也在更新,而且是比较低调的进行着更新,所以并不是所有人都清楚CDN对动态加速的效果.其 ...
- C# Html Agility Pack
using System; using HtmlAgilityPack; using System.IO; using System.Text; using System.Text.RegularEx ...
- angularjs中的时间格式化过滤
本地化日期格式化: ({{ today | date:'medium' }})Nov 19, 2015 3:57:48 PM ({{ today | date:'short' }})11/19/15 ...
- EasyUI datagrid border处理,加边框,去边框,都能够
以下是EasyUI 官网上处理datagrid border的demo: 主要是这句: $('#dg').datagrid('getPanel').removeClass('lines-both li ...
- 自动测试工具agitarOne 初体验之-MockingBird的使用
大名鼎鼎的AgitarOne就不用解释了,在昨天的随笔中有一些解释,今天主要说说Agitar 中Mockingbird的使用. 为了提高测试代 码的Coverage,仅仅靠Agita ...
- 启动spring boot 异常
再我搭建spring boot工程后,run application的时候抛出下面异常 Exception /slf4j-log4j12-.jar). If you are using WebLogi ...
- Weblogic配置故障转移
前提:实现负载均衡,即当访问项目时,会通过代理服务器将请求分发到不同的服务器上. weblogic的故障转移配置 在项目的WEB-INF目录下创建weblogic.xml <!DOCTYPE w ...
- openresty 定时器
[1]nginx定时器应用 (1)文件目录结构 (2)nginx.conf配置 lua_package_path "/usr/local/lib/ubcsrvd/lualib/?.lua;; ...