【LOJ#6074】子序列(动态规划)
【LOJ#6074】子序列(动态规划)
题面
题解
考虑一个暴力\(dp\)。
设\(f[i][c]\)表示当前在第\(i\)位,并且以\(c\)结尾的子序列个数。
那么假设当前位为\(a\),强制把\(a\)接在所有出现过的子序列后面,再加上一个单独的\(a\)。
也就是\(f[i][a]=\sum_j f[i-1][j]\),其他的\(f[i][k]=f[i-1][k]\)。
显然这样一个转移是可以写成矩阵形式的,预处理矩阵的前缀和和矩阵逆的前缀和就可以很方便的计算答案,这样子的复杂度是字符集大小三方的。
发现我们要的只是一个行向量或者一个列向量。这样子可以优化单次矩乘为字符集大小平方,然而我们直接按照\(dp\)转移就好了,就变成了字符集大小了。
那么最终的答案就是一个行向量和一个列向量相乘即可。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MOD 1000000007
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
char s[MAX];
int n,Q;
int a[10][10],S[10],L[MAX][10],R[MAX][10];
int main()
{
scanf("%s",s+1);n=strlen(s+1);Q=read();
for(int i=0;i<=9;++i)a[i][i]=S[i]=R[0][i]=1;
for(int i=1;i<=n;++i)
{
int c=s[i]-96,tmp;
for(int j=0;j<=9;++j)tmp=a[j][c],a[j][c]=S[j],S[j]=(2ll*S[j]-tmp+MOD)%MOD;
for(int j=0;j<=9;++j)R[i][j]=S[j];
}
memset(a,0,sizeof(a));memset(S,0,sizeof(S));
for(int i=0;i<=9;++i)a[i][i]=1,L[0][i]=!i;
for(int i=1;i<=n;++i)
{
int c=s[i]-96,tmp;
for(int j=0;j<=9;++j)tmp=(a[c][j]+S[j])%MOD,S[j]=(S[j]-tmp+MOD)%MOD,a[c][j]=(a[c][j]+tmp)%MOD;
for(int j=0;j<=9;++j)L[i][j]=(a[0][j]+S[j])%MOD;
}
while(Q--)
{
int l=read(),r=read(),ans=MOD-1;
for(int i=0;i<=9;++i)ans=(ans+1ll*R[r][i]*L[l-1][i])%MOD;
printf("%d\n",ans);
}
return 0;
}
【LOJ#6074】子序列(动态规划)的更多相关文章
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)
题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...
- loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)
题意 题目链接 Sol 设\(f[i][j]\)表示前\(i\)个位置中,以\(j\)为结尾的方案数. 转移的时候判断一下\(j\)是否和当前位置相同 然后发现可以用矩阵优化,可以分别求出前缀积和逆矩 ...
- hdu1231最大连续子序列(动态规划)
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
- 【ACM】最长公共子序列 - 动态规划
最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...
- 最长上升子序列(动态规划递推,LIS)
1759:最长上升子序列 题目: 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的 ...
- C++求解汉字字符串的最长公共子序列 动态规划
近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...
- [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)
https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ...
随机推荐
- Django组件之认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Dja ...
- 网站数据分析&初始来源
数据分析:如何追踪访客初始来源_搜索学院_百度搜索资源平台 https://ziyuan.baidu.com/college/articleinfo?id=260 网站数据分析:如何追踪访客初始来源 ...
- vue路由动态过渡效果
不多说,直接上代码 import Vue from 'vue' //引入vue import VueRouter from 'vue-router' //引入路由 Vue.use(VueRouter) ...
- C#中使用打印日志
在日常的工作中经常需要日志,这样能够很容易定位到代码中的一些错误,.Net中有自带的日志接口.并没有仔细去研究,这里是我自己写的日志接口,记录下来以便以后用到,根据时间打印相关的日志文件,代码如下: ...
- MySQL dump文件导入
1 打开cmd 输入要导入的数据库,用户名,密码,dump文件路径 mysql -u employees <E:\employees_db\load_departments.dump
- [转帖]一个FORK的面试题
一个FORK的面试题 https://coolshell.cn 搞不懂 fork 的含义. Linux 里面的线程不是教科书上面的标准的线程 好像用 父子进程来进行 模拟线程的处理 父子线程应该共享 ...
- 【学亮IT手记】利用字节流复制文件
- python爬虫之scrapy安装(一)
简介: Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrap ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
今天服务器遇到了一个很熟悉的问题, 输入 #mysql -u root -p ERROR 2002 (HY000):Can't connect to local MySQL server ...
- 排查 Maxwell can not find database 并且使用 MySQL binlog 解决相关问题
目前我们在使用 Maxwell 在读线上机器的 binlog 同步我们的离线数据库. 这次错误定位上,首先线要确定问题是发生在生产者 还是队列 还是消费者.经过查看各机器上任务的运行日志,定位到了问题 ...