【LOJ#6074】子序列(动态规划)

题面

LOJ

题解

考虑一个暴力\(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】子序列(动态规划)的更多相关文章

  1. LOJ #6074. 「2017 山东一轮集训 Day6」子序列

    #6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...

  2. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)

    题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...

  3. loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)

    题意 题目链接 Sol 设\(f[i][j]\)表示前\(i\)个位置中,以\(j\)为结尾的方案数. 转移的时候判断一下\(j\)是否和当前位置相同 然后发现可以用矩阵优化,可以分别求出前缀积和逆矩 ...

  4. hdu1231最大连续子序列(动态规划)

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  5. HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)

    6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...

  6. 【ACM】最长公共子序列 - 动态规划

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  7. 最长上升子序列(动态规划递推,LIS)

    1759:最长上升子序列 题目: 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的 ...

  8. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...

  9. [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)

    https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ...

随机推荐

  1. Django组件之认证系统

      Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Dja ...

  2. 网站数据分析&初始来源

    数据分析:如何追踪访客初始来源_搜索学院_百度搜索资源平台 https://ziyuan.baidu.com/college/articleinfo?id=260 网站数据分析:如何追踪访客初始来源 ...

  3. vue路由动态过渡效果

    不多说,直接上代码 import Vue from 'vue' //引入vue import VueRouter from 'vue-router' //引入路由 Vue.use(VueRouter) ...

  4. C#中使用打印日志

    在日常的工作中经常需要日志,这样能够很容易定位到代码中的一些错误,.Net中有自带的日志接口.并没有仔细去研究,这里是我自己写的日志接口,记录下来以便以后用到,根据时间打印相关的日志文件,代码如下: ...

  5. MySQL dump文件导入

    1 打开cmd 输入要导入的数据库,用户名,密码,dump文件路径 mysql -u employees <E:\employees_db\load_departments.dump

  6. [转帖]一个FORK的面试题

    一个FORK的面试题 https://coolshell.cn 搞不懂 fork 的含义. Linux 里面的线程不是教科书上面的标准的线程 好像用 父子进程来进行 模拟线程的处理 父子线程应该共享 ...

  7. 【学亮IT手记】利用字节流复制文件

  8. python爬虫之scrapy安装(一)

    简介: Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrap ...

  9. 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     ...

  10. 排查 Maxwell can not find database 并且使用 MySQL binlog 解决相关问题

    目前我们在使用 Maxwell 在读线上机器的 binlog 同步我们的离线数据库. 这次错误定位上,首先线要确定问题是发生在生产者 还是队列 还是消费者.经过查看各机器上任务的运行日志,定位到了问题 ...