首页 > 其他分享 >Codeforces 1835E - Old Mobile

Codeforces 1835E - Old Mobile

时间:2023-06-22 09:11:09浏览次数:59  
标签:字符 Old Mobile 1835E 确定 按下 Backspace dfrac MAXN

首先先观察到一个非常浅显的性质:就是一个位置在序列中不是第一次出现,那么到这个位置的时候打出这个字符需要恰好一次按键,这是因为我们肯定在打出第一次出现这个字符的位置的时候已经知道哪个键对应这个字符了,到那个位置的时候直接敲一下就 ok 了。

也就是我们只用关心这个序列中出现了多少种不同的数,设为 \(A\),并假设序列就是 \(0,1,2,\cdots,A-1\)。那么考虑一次从啥也不知道到打出这个句子出来经过怎么样的过程:显然是你先随机乱按,按出一个与原序列的 \(\text{LCP}=l_1\),长度为 \(l_1+l_2\) 的序列,然后突然按到了 Backspace,然后再把剩余 \(l_2-1\) 个与 LCP 不符合的字符删掉,然后再确定剩余的数字键,策略是如果下一个字符你在之前猜 Backspace 的过程中就确定了,那么直接按出来,否则乱猜一个键,如果符合就继续,不符合就按 BACKSPACE 再猜剩下的。当然比较特殊的一种情况是运气比较好连 Backspace 都不知道就直接打出了原句子,还有一种可能是 \(l_2=0\),此时按下 BACKSPACE 之后需要把删掉的那个字符补回来。

本人思考时候一个比较 naive 的思路是你枚举这个 \(l_1,l_2\),这样你大概可以得到一个 \(n^4\) 的做法,由于比较垃圾就不再赘述。考虑怎么优化到 \(n^2\):摊贡献。在探索 Backspace 的过程中,我们考虑将 \(l_2\) 的贡献摊到按下错误字符的 DP 过程中计算。在打出剩余部分的过程中,如果一个字符之前我们已经确定了它的位置,那么我们就将这个贡献摊到发现键盘上哪个键对应这个字符的时候计算。这样我们考虑设三个 \(dp\) 数组:

  • \(f_{i,j}\) 表示已经知道了 Backspace 键是什么,还剩 \(i\) 个 \([0,A-1]\) 中的键没有确定,\(j\) 个 \([A,m-1]\) 中的键没有确定的期望次数。
  • \(g_{i,j}\) 表示还没知道 Backspace 键是什么,目前 \(l_2\ne 0\),还剩 \(i\) 个 \([0,A-1]\) 中的键没有确定,\(j\) 个 \([A,m-1]\) 中的键没有确定的期望次数。
  • \(h_{i,j}\) 表示还没知道 Backspace 键是什么,目前 \(l_2=0\),还剩 \(i\) 个 \([0,A-1]\) 中的键没有确定,\(j\) 个 \([A,m-1]\) 中的键没有确定的期望次数。

考虑转移,先考虑 \(f\) 的转移,分三种情况:

  • 按下的键就是下一个字符,概率为 \(\dfrac{1}{i+j}\),贡献 \(f_{i-1,j}+1\)。
  • 按下的键不是下一个字符,但是是另一个 \([0,A-1]\) 中没有被确定的字符,概率为 \(\dfrac{i-1}{i+j}\),贡献 \(f_{i-1,j}+3\),这个 \(3\) 是因为我按下了一个键,Backspace 把它去掉,下次再遇到时还需要一次(摊贡献)。
  • 按下的键是一个 \([A,m-1]\) 中没有被确定的字符,概率为 \(\dfrac{j}{i+j}\),贡献 \(f_{i,j-1}+3\)。

再考虑 \(g\) 的转移,分三种情况:

  • 按下的键是 Backspace,概率为 \(\dfrac{1}{i+j+1}\),贡献 \(f_{i,j}+1\)。
  • 按下的键是一个 \([0,A-1]\) 中没被确定的字符,概率为 \(\dfrac{i}{i+j+1}\),贡献 \(g_{i-1,j}+3\),这个 \(3\) 是因为我按下一个键,在确定 Backspace 后要把这个字符删掉,在后面我遇到这个字符时又要按一次。
  • 按下的键是一个 \([A,m-1]\) 中没被确定的字符,概率为 \(\dfrac{j}{i+j+1}\),贡献 \(g_{i,j-1}+2\)。

最后考虑 \(h\),分四种情况:

  • 按下的键是下一个字符,概率为 \(\dfrac{1}{i+j+1}\),贡献 \(h_{i-1,j}+1\)。
  • 按下的键不是下一个字符但是是某个 \([0,A-1]\) 中没被确定的字符,概率为 \(\dfrac{i-1}{i+j+1}\),贡献 \(g_{i-1,j}+3\)。
  • 按下的键是某个 \([A,m-1]\) 中没被确定的字符,概率为 \(\dfrac{j}{i+j+1}\),贡献 \(g_{i,j-1}+2\)
  • 按下的键是 Backspace,概率为 \(\dfrac{1}{i+j+1}\),贡献 \(f_{i,j}+2\),\(2\) 是因为我要把删掉的字符补回来。

于是做完了,复杂度 \(O(n^2)\)。

const int MAXN=1e3+1;
const int MOD=1e9+7;
int n,m,A,B,f[MAXN+5][MAXN+5],g[MAXN+5][MAXN+5],h[MAXN+5][MAXN+5],inv[MAXN+5];
int main(){
	scanf("%d%d",&n,&m);set<int>st;
	for(int i=(inv[0]=inv[1]=1)+1;i<=MAXN;i++)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
	for(int i=1,x;i<=n;i++)scanf("%d",&x),st.insert(x);
	A=st.size();B=m-A;
	for(int i=1;i<=A;i++)for(int j=0;j<=B;j++){
		f[i][j]=1ll*(i-1)*inv[i+j]%MOD*(f[i-1][j]+3)%MOD;
		f[i][j]=(f[i][j]+1ll*inv[i+j]*(f[i-1][j]+1))%MOD;
		if(j)f[i][j]=(f[i][j]+1ll*inv[i+j]*j%MOD*(f[i][j-1]+2))%MOD;
	}
	for(int i=0;i<=A;i++)for(int j=0;j<=B;j++){
		g[i][j]=1ll*inv[i+j+1]*f[i][j]%MOD;
		if(i)g[i][j]=(g[i][j]+1ll*inv[i+j+1]*i%MOD*(g[i-1][j]+3))%MOD;
		if(j)g[i][j]=(g[i][j]+1ll*inv[i+j+1]*j%MOD*(g[i][j-1]+2))%MOD;
	}
	for(int i=1;i<=A;i++)for(int j=0;j<=B;j++){
		h[i][j]=1ll*inv[i+j+1]*(h[i-1][j]+1)%MOD;
		h[i][j]=(h[i][j]+1ll*(i-1)*inv[i+j+1]%MOD*(g[i-1][j]+3))%MOD;
		if(j)h[i][j]=(h[i][j]+1ll*j*inv[i+j+1]%MOD*(g[i][j-1]+2))%MOD;
		h[i][j]=(h[i][j]+1ll*inv[i+j+1]*(f[i][j]+2))%MOD;
	}
	int res=n-A;
	res=(res+1ll*inv[m+1]*(f[A][B]+1))%MOD;
	res=(res+1ll*inv[m+1]*(h[A-1][B]+1))%MOD;
	res=(res+1ll*inv[m+1]*(A-1)%MOD*(g[A-1][B]+3))%MOD;
	res=(res+1ll*inv[m+1]*B%MOD*(g[A][B-1]+2))%MOD;
	printf("%d\n",res);
	return 0;
}

标签:字符,Old,Mobile,1835E,确定,按下,Backspace,dfrac,MAXN
From: https://www.cnblogs.com/tzcwk/p/Codeforces-1835E.html

相关文章

  • 将assets or raw folder文件复制到sd卡
    有时候我们需要把程序的raw文件放在sd卡中,其实有时候这样做可以释放资源,有时候可能是使坏呼呼voidcopyAssets(){String[]files;try{files=this.getResources().getAssets().list("");}catch(IOExceptione1){retur......
  • BMZCTF:oldmodem
    http://bmzclub.cn/challenges#oldmodem使用file命令查看下,发现是wav文件但是修改后缀为wav后缀后并没有看出什么也没听出什么然后根据题目名称得知这是modem文件,装个minimoden去识别这个文件直接kali中:sudoapt-getinstallminimodem这个题目原来还有个提示没给就是这个modem......
  • 快时钟 慢时钟交互如何检查set/hold time
    参考书籍《StaticTimingAnalysisforNanometerDesign》 慢时钟——>快时钟首先进行时钟约束create_clock-nameCLKM-period20-waveform{010}[get_portsCLKM]create_clock-nameCLKP-period5-waveform{02.5}[get_portsCLKP]  由于电路是从慢时钟......
  • Oracle最高可用性架构(MAA)|黄金级(GOLD)
    1、什么是MAA参考之前的文章:1、Oracle最高可用性架构(MAA)|青铜级(BRONZE)https://www.cnblogs.com/mingfan/p/16804556.html2、Oracle最高可用性架构(MAA)|白银级(SILVER) https://www.cnblogs.com/mingfan/p/17464913.html2、黄金级(GOLD)MAA我们都知道,单点是系统高可用的......
  • 开源即时通讯IM框架MobileIMSDK的H5端开发快速入门
    ► 相关链接:① MobileIMSDK-H5端的详细介绍② MobileIMSDK-H5端的开发手册new(* 精编PDF版)一、技术准备您是否已对Web端即时通讯技术有所了解?1)新手入门贴:史上最全Web端即时通讯技术原理详解2)Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE您需要对WebSocket技......
  • Krylov子空间与Arnoldi过程
    一、应用背景Krylov子空间方法是模型降阶(MOR)的一种,Krylov子空间方法就是在Krylov子空间中寻找近似解。 二、Krylov子空间 n是原始矩阵的维度,m为降阶后矩阵的维度,通常m<<n。 三、Arnoldi过程:计算Km的一组正交  对应上述MGS过程的python代码:importnumpy......
  • GoldenEye项目实战
    前言“操千曲而后晓声,观千剑而后识器”,下载靶机项目实战提升自我,这是一个涉及到渗透与CTF联合的实战项目。Descript:我最近完成了一个OSCP类型的易受攻击机器的创建,它以伟大的詹姆斯·邦德电影(甚至更好的n64游戏)《黄金眼》为主题。目标是获得根并捕获秘密的GoldenEye代码-flag......
  • c# aveva marine link folder
    publicclassLinkWorld{publicstaticDbElementLinkWLD=>Aveva.Pdms.Database.DbType.Design.FindElements(DbElementTypeInstance.LINKWLD).FirstOrDefault();}publicclassLinkDescription{publicDbElementCurElement{g......
  • 【React工作记录九十九】ant design mobile实现tab滚动效果和闪屏小记
    前言大家好我是歌谣今天继续给大家带来前端工作中遇到的实际性问题如何实现一个tab效果以及闪屏问题效果演示(tab滚动效果)案例遇到问题先去查api查百度一开始我以为是安卓的功能直接api打开<DemoBlocktitle='超长自动滚动'padding='0'><TabsdefaultActiveKey=......
  • jquery Mobile点击显示加载等待效果
    点击某个按钮或链接时,触发等待加载效果:<script><!--$(document).bind("mobileinit",function(){});$(function(){//默认设置,一个小圈圈在转$('#default').live('tap',function(){$.mobile.loadingMessageTe......