[日常训练]string
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的更多相关文章
- 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...
- 「日常训练」 Fire!(UVA-11624)
与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...
- 「日常训练」Common Subexpression Elimination(UVa-12219)
今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...
- 集训队日常训练20181117 DIV2
大佬们一顿操作猛如虎,拼命AC强啊 4262: 区间异或 Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal ...
- [日常训练]article
Description 小今天来写作文啦! 小非常善于堆砌辞藻.在洋洋洒洒写了一长篇之后,小发现作文中很多段落都似曾相识.小认为,如果一段字符在文章开头,结尾和中间都出现过,那么这段字符就可以被认为是 ...
- 日常训练 dfs 之 拓扑排序
今天被拓扑排序给折磨了一天,主要就是我的一个代码有点小bug,真难找... 先来看看我今天写的题目吧! C. Fox And Names Fox Ciel is going to publish a ...
- 日常训练赛 Problem C – Complete Naebbirac’s sequence
比赛链接https://vjudge.net/contest/256988#status/17111202012/C/0/ 大意:三个操作,使得输入的数中,从1-n,每一个数出现的次数相同. wa代码 ...
- 【日常训练】 Help Greg the Dwarf(CodeForces-99E)
题意与分析 题意是这样的,问你把一个长方形从一个L型街道的一端移动到另一端,固定了该长方形的长,求他的最大宽. 这种问题我是第一次独立解决(以前都是抱队友大腿QAQ),现在没法子只好自己硬着头皮做,看 ...
- 【日常训练】Help Victoria the Wise(Codeforces 99C)
题意与分析 这题意思是这样的:在正方体的六面镶嵌给定颜色的宝石(相同颜色不区分),然后问最多有几种彼此不等价(即各种旋转过后看起来一致)的方案. 其实可以乱搞,因为范围只有720.求出全排列,然后每个 ...
随机推荐
- 生成Tab键或逗号分隔的CSV
<?php header("Content-type:text/csv;charset=utf-8"); header("Content-Disposition:a ...
- Unable to simultaneously satisfy constraints.
在进行版本的迭代更新时,新功能需求需要对主页面的UI进行重新的布局,但是,报了错误,出了好多约束方面的问题: Unable to simultaneously satisfy constraints. ...
- Hibernate 系列 03 - 使用Hibernate完成持久化操作
引导目录: Hibernate 系列教程 目录 康姆昂,北鼻,来此狗.动次打次,Hibernate继续走起. 目录: 使用Hibernate实现按主键查询 使用Hibernate实现数据库的增.删.改 ...
- C#中DateTime.Ticks属性及Unix时间戳转换
1.相关概念 DateTime.Ticks:表示0001 年 1 月 1 日午夜 12:00:00 以来所经历的 100 纳秒数,即Ticks的属性为100纳秒(1Ticks = 0.0001毫秒). ...
- Hadoop技巧(02):时间同步
阅读目录 序 时间同步 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 在实际部署 ...
- 2015-12-01 SQL查询语句基础
1.查询全体学生的学号与姓名select sno,snamefrom student;3.查询全体学生的详细信息select *from student;4.查询全体学生的姓名及其出生年份select ...
- sql 优化
1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表driving table)将被最先处 ...
- dubox首次调用消费者执行两次问题
dubbox+zookeeper服务开启后 Dubbo的超时重试机制为服务容错.服务稳定提供了比较好的框架支持,但是在一些比较特殊的网络环境下(网络传输慢,并发多)可能由于服务响应慢,Dubbo自身的 ...
- linux基本知识1
ls命令: -l:长格式 文件类型:第1位 -:普通文件 d:目录文件 b:块设备文件(block) c:字符设备文件(character) l:符号链接文件(symbolic link file) ...
- 基于UDP的网络编程
与TCP编程相比较,UDP缺少了connect().listen()及accept()函数,这是由于UDP协议无连接的特性,不用维护TCP的连接.断开等状态. UDP编程框图 API函数 socket ...