CodeForces 1426F Number of Subsequences
题意
给定一个长度为 \(n\) 的串,只包含 abc
和通配符。通配符可以替换 abc
的一个。求所有得到的字符串中子序列 abc
出现的次数,对 \(10^9+7\) 取模。
\(\texttt{Data Range:}n\leq 2\times 10^5\)
题解
哇哈哈哈我智商终于恢复了。
比较套路,但其实这个东西我一开始是用类似于期望的东西来想的。
记通配符的数量为 \(m\)。
考虑设 \(f_{i,j}\) 表示所有 \(3^m\) 个字符串的前 \(i\) 个字符中,子序列 a
,ab
,abc
的数量之和。
首先当给定字符串的第 \(i\) 个字符为 a
的时候,有如下转移:
\]
为 b
的时候有如下转移:
\]
为 c
的时候有如下转移:
\]
这三个转移都很平凡,这里不多赘述。
接下来是为通配符的情况,需要讨论一下。
注意到我们肯定可以将所有 \(3^{m}\) 个字符串中直到 \(i-1\) 的前缀划分为三组,每组的字符串相同。
所以说每组字符串的中的 a
,ab
,abc
的数量变成了 \(\frac{f_{i-1,1}}{3}\),\(\frac{f_{i-1,2}}{3}\) 和 \(\frac{f_{i-1,3}}{3}\)。
于是考虑将第一组的后面加一个 a
,第二组加一个 b
,第三组加一个 c
。这样子我们就可以写出一个转移方程:
\]
整理一下得到以下转移:
\]
线性 DP 就没了。
有一个加强版就是说多组询问求任意子段的答案。注意到 \(f_{i}\) 只与 \(f_{i-1}\) 有关所以可以写成一个 \(4\times 4\) 的矩阵,然后用线段树维护矩阵乘积就好了。可能会算重,于是除掉一下就差不多了。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51,MOD=1e9+7,INV3=333333336;
ll n,m,pw=1;
char ch[MAXN];
ll f[MAXN][3];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
int main()
{
n=read(),scanf("%s",ch+1);
for(register int i=1;i<=n;i++)
{
ch[i]=='?'?m++,pw=(li)pw*3%MOD:1;
}
for(register int i=1;i<=n;i++)
{
f[i][1]=f[i-1][1],f[i][2]=f[i-1][2],f[i][3]=f[i-1][3];
if(ch[i]=='a')
{
f[i][1]=(f[i][1]+pw)%MOD;
}
if(ch[i]=='b')
{
f[i][2]=(f[i][2]+f[i-1][1])%MOD;
}
if(ch[i]=='c')
{
f[i][3]=(f[i][3]+f[i-1][2])%MOD;
}
if(ch[i]=='?')
{
f[i][1]=(f[i][1]+(li)pw*INV3%MOD)%MOD;
f[i][2]=(f[i][2]+(li)f[i-1][1]*INV3)%MOD;
f[i][3]=(f[i][3]+(li)f[i-1][2]*INV3)%MOD;
}
}
printf("%d\n",f[n][3]);
}
CodeForces 1426F Number of Subsequences的更多相关文章
- Codeforces Round #674 (Div. 3) F. Number of Subsequences 题解(dp)
题目链接 题目大意 给你一个长为d只包含字符'a','b','c','?' 的字符串,?可以变成a,b,c字符,假如有x个?字符,那么有\(3^x\)个字符串,求所有字符串种子序列包含多少个abc子序 ...
- codeforces Hill Number 数位dp
http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits: 5000 MS Memory Limits: ...
- CodeForces 689D Friends and Subsequences (RMQ+二分)
Friends and Subsequences 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/H Description Mi ...
- CodeForces - 803F: Coprime Subsequences(莫比乌斯&容斥)
Let's call a non-empty sequence of positive integers a1, a2... ak coprime if the greatest common div ...
- 【codeforces 803F】Coprime Subsequences
[题目链接]:http://codeforces.com/contest/803/problem/F [题意] 给你一个序列; 问你这个序列里面有多少个子列; 且这个子列里面的所有数字互质; [题解] ...
- codeforces 27E Number With The Given Amount Of Divisors
E. Number With The Given Amount Of Divisors time limit per test 2 seconds memory limit per test 256 ...
- Codeforces 27E. Number With The Given Amount Of Divisors (暴力)
题目链接:http://codeforces.com/problemset/problem/27/E 暴力 //#pragma comment(linker, "/STACK:1024000 ...
- Codeforces 235E Number Challenge
http://codeforces.com/contest/235/problem/E 远距离orz......rng_58 证明可以见这里(可能要FQ才能看到) 还是copy一下证明吧: 记 $$f ...
- CodeForces 1151E Number of Components
题目链接:http://codeforces.com/problemset/problem/1151/E 题目大意: n个人排成一个序列,标号为 1~n,第 i 个人的学习成绩为 ai,现在要选出学习 ...
随机推荐
- 使用VMware虚拟机安装RHEL7(RedHat Enterprise Linux7)步骤
准备工具: 1.VMware Workstation 14 2.RedHat Enterprise Linux 7.0镜像文件 在虚拟机内设置操作系统的硬件标准 单击"创建新的虚拟机&quo ...
- 关于Python中以字母r,或字母u 开头的字符串
(1)以r或R开头的Python中的字符串表示(非转义的)原始字符串 python里面的字符,如果开头处有个r,比如: (r'^time/plus/\d{1,2}/$', hours_ahead) ...
- 二维数组,column可以从后往前循环
- 013 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 07 基本数据类型变量的存储
013 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 07 基本数据类型变量的存储 变量和它的值如何在内存中进行存储的? 前面学习过:Java中的数据类型分为基本 ...
- Tensorflow学习笔记No.4.1
使用CNN卷积神经网络(1) 简单介绍CNN卷积神经网络的概念和原理. 已经了解的小伙伴可以跳转到Tensorflow学习笔记No.4.2学习如和用Tensorflow实现简单的卷积神经网络. 1.C ...
- Androng,一个针对Android的Pong克隆
下载application from Android market 下载source - 532 KB 内容 IntroductionAndroid游戏开发 活动视图绘图使用CanvasAnimati ...
- Docker开启远程连接,本地IDEA使用docker插件连接(不认证的版本和认证的版本都有)
前言 在学校学习的时候,要部署一个Java程序,一般是打成war包,放到服务器上的tomcat的webapp里面去: 后来SpringBoot出现内置了tomcat,就直接打成jar包,丢到服务器任何 ...
- 震惊!OI居然还考天体运动
看图说话 看这里: 标签: 标签竟然还是模拟,简直活到爆,物理老师狂喜
- linux(centos8):使用cgroups做资源限制
一,什么是cgroups? 1,cgroups是资源的控制组,它提供了一套机制用于控制一组特定进程对资源的使用. cgroups绑定一个进程集合到一个或多个限制资源使用的子系统上. 2, cg ...
- nginx安全:用limit_req_zone/limit_req限制连接速率(流量控制/限流)
一,limit_req的用途: 1,官方文档地址: http://nginx.org/en/docs/http/ngx_http_limit_req_module.html 2,用途: 限制用户在给定 ...