Description

给定一个长度为$n$的字符串,串中的字符保证是前$k$个小写字母。你可以在字符串后再添加$m$个字符,使得新字符串所包含的不同的子序列数量尽量多。当然,前提是只能添加前$k$个小写字母。求新的长度为$n+m$的串最多的不同子序列数量。答案对$10^9+7$取模。

Input

输入第一行两个数$m,k$。
接下来一行一个字符串,长度为$n$,表示原始的字符串$s$。

Output

一个数,表示答案。

Sample Input

1 3
ac

Sample Output

8

HINT

$n,m\;\leq\;10^6,k\;\leq\;26$

Solution

当$m=0$时,

$lst[i]$表示字符$i$上一次出现的位置,

$f[i]$表示以第$i$位结尾的新出现的不同的子序列的个数.

以第$x(lst[i]\;\leq\;x<i)$位结尾的新出现的子序列末尾加上$s[i]$为一个新的子序列.(反证法可证$x(0<x<lst[i])$不可行)

$f[i]=\sum_{j=lst[s[i]]}^{i-1}f[j]$.

这个可以用前缀和优化.

当$m\not=0$时,

设$sum[i]=\sum_{j=1}^{i}f[j]$,

则$f[i]=sum[i-1]-sum[lst[j]-1](n<i\;\leq\;n+m)$

$f[i]$最大,即$lst[j]-1$最小.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define K 2000005
#define M 1000000007
using namespace std;
int s[K],sum,tmp,m,n,t;
bool u[K];char c;
int f[K],lst[K];
inline void Aireen(){
scanf("%d%d",&m,&t);
c=getchar();
for(n=1;scanf("%c",&c)==1;++n){
if(!(c>='a'&&c<='z'))
break;
if(lst[c-'a'])
f[n]=(s[n-1]-s[lst[c-'a']-1]+M)%M;
else f[n]=(s[n-1]+1)%M;
s[n]=(s[n-1]+f[n])%M;
lst[c-'a']=n;
}
--n;
if(t) for(int i=n+1,j,k;i<=n+m;++i){
k=lst[0];j=0;
for(int l=1;l<t;++l){
if(lst[l]<k){
k=lst[l];j=l;
}
}
printf("j=%d\n",j);
if(lst[j])
f[i]=(s[i-1]-s[lst[j]-1]+M)%M;
else f[i]=(s[i-1]+1)%M;
s[i]=(s[i-1]+f[i])%M;
lst[j]=i;
}
printf("%d\n",(s[n+m]+1)%M);
}
int main(){
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}

因为卡空间$1MB$,每次转移只与$f[lst[i]-1]$有关,所以只需$O(k)$的空间.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define K 26
#define M 1000000007
using namespace std;
int s[K],lst[K],sum,tmp,m,n,t;
char c;
inline void Aireen(){
scanf("%d%d",&m,&t);
c=getchar();
for(n=1;scanf("%c",&c)==1;++n){
if(!(c>='a'&&c<='z'))
break;
tmp=s[c-'a'];s[c-'a']=sum;
if(lst[c-'a']) sum=((sum<<1)%M-tmp+M)%M;
else sum=((sum<<1)+1)%M;
lst[c-'a']=n;
}
--n;
if(t) for(int i=1,j,k;i<=m;++i){
k=lst[0];j=0;
for(int l=1;l<t;++l){
if(lst[l]<k){
k=lst[l];j=l;
}
}
tmp=s[j];s[j]=sum;
if(lst[j]) sum=((sum<<1)%M-tmp+M)%M;
else sum=((sum<<1)+1)%M;
lst[j]=i+m;
}
printf("%d\n",(sum+1)%M);
}
int main(){
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}

[日常训练]string的更多相关文章

  1. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)

    题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...

  2. 「日常训练」 Fire!(UVA-11624)

    与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...

  3. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  4. 集训队日常训练20181117 DIV2

    大佬们一顿操作猛如虎,拼命AC强啊 4262: 区间异或  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal ...

  5. [日常训练]article

    Description 小今天来写作文啦! 小非常善于堆砌辞藻.在洋洋洒洒写了一长篇之后,小发现作文中很多段落都似曾相识.小认为,如果一段字符在文章开头,结尾和中间都出现过,那么这段字符就可以被认为是 ...

  6. 日常训练 dfs 之 拓扑排序

    今天被拓扑排序给折磨了一天,主要就是我的一个代码有点小bug,真难找... 先来看看我今天写的题目吧! C. Fox And Names Fox Ciel is going to publish a ...

  7. 日常训练赛 Problem C – Complete Naebbirac’s sequence

    比赛链接https://vjudge.net/contest/256988#status/17111202012/C/0/ 大意:三个操作,使得输入的数中,从1-n,每一个数出现的次数相同. wa代码 ...

  8. 【日常训练】 Help Greg the Dwarf(CodeForces-99E)

    题意与分析 题意是这样的,问你把一个长方形从一个L型街道的一端移动到另一端,固定了该长方形的长,求他的最大宽. 这种问题我是第一次独立解决(以前都是抱队友大腿QAQ),现在没法子只好自己硬着头皮做,看 ...

  9. 【日常训练】Help Victoria the Wise(Codeforces 99C)

    题意与分析 这题意思是这样的:在正方体的六面镶嵌给定颜色的宝石(相同颜色不区分),然后问最多有几种彼此不等价(即各种旋转过后看起来一致)的方案. 其实可以乱搞,因为范围只有720.求出全排列,然后每个 ...

随机推荐

  1. JDBC关于时间的存取

    Oracle数据库默认时间存储是java.sql.date,而java程序中的时间默认是java.util.date,所以通过JDBC存取的 时候会涉及到时间的转换问题. 1.日期存取 存入数据库的时 ...

  2. 从网上找的 visual studio 的各个版本下载地址,vs2010/vs2012/vs2013带注册码

    从网上找的 visual studio 的各个版本下载地址,很全,从 6.0 一直 到 vs2013,要的拿去吧... Microsoft Visual Studio 6.0 下载:英文版360云盘下 ...

  3. ArcGIS Engine开发前基础知识(4)

    ArcGIS不同开发方式的比较 关于GIS应用软件的开发,通常有三种方式:C/S架构.网络GIS和移动GIS.ArcGIS平台提供了对三种开发方式的支持,对于采用从C/S架构的大多数开发者来讲,首先想 ...

  4. 阶段一:AsyncTask的三个属性值和四个步骤

    “阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 最近学到用AsyncTask来处理有关网络的操作.虽然代码看上去不是很复杂,但仍有很多地方有疑惑.所以研读了一下A ...

  5. Android多媒体框架图

    Android多媒体整体架构图 MediaPlayer框架图 Camera框架图 SoundRecorder框架图 VideoCamera框架图 OpenCore与Skia ALSA Audio框架图 ...

  6. 在VMware上安装Linux(CentOS)

    1. 新建虚拟机 2. 新建虚拟机向导 3. 创建虚拟空白光盘 4. 安装Linux系统对应的CentOS版 5. 虚拟机命名和定位磁盘位置 6. 处理器配置,看自己是否是双核.多核 7. 设置内存为 ...

  7. JavaScript 函数

    JavaScript 函数 介绍:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.嗯,就像Java中封装的方法一样. 将脚本编写为函数,就可以避免页面载入时执行该脚本. 函数包含着一些代码 ...

  8. Linux安装详情图解

    本文讲解Linux的安装 因为是纯属学习使用,所以安装在了虚拟机里   需要软件: VirtualBox-5.1.10 ubuntu-16.04.1-desktop-amd64 说明: 虚拟机可以选择 ...

  9. 《Note --- Unreal 4 --- PersonaHowToMovement》

    https://docs.unrealengine.com/latest/CHN/Gameplay/HowTo/CharacterMovement/index.html 这里的demo是按照一些per ...

  10. input输入框的光标

    上午的时候,以前一起配合Java后端的哥们问了个input光标的问题. 需求是这样:只能输入数字的input(一开始以为是输入金额这些的,后来才晓得是用来填写手机号) 他采用是直接百度来的如下方法: ...