题目描述

https://loj.ac/problem/6074

题解

对于子序列的dp,我们可以设置一个dp。

我们设dp[i]表示以i这个字符结尾的子序列个数,转移为dp[i]+=∑dp[k]-dp[i]。其实我们发现这样等价于dp[i]=∑dp[k]。

另外我们还要再设一个空字符的位置表示空字符,所以我们的转移矩阵长成这样。

1 0 1 0 0

0 1 1 0 0

0 0 1 0 0

0 0 1 1 0

0 0 1 0 1

我们一开始是空的,所以转移矩阵为

0 0 0 0 1

最后我们要归为一个答案,所以还要乘上一个列矩阵。

1

1

1

1

0

直接做是N^3的,我们发现这个矩阵长得非常有特点,我们把它的逆矩阵求出来之后发现。

1 0 -1 0 0

0 1 -1 0 0

0 0 1 0 0

0 0 -1 1 0

0 0 -1 0 1

所以我们的思路就是让行向量*1~l-1的逆矩阵再乘上1~r的正矩阵,在乘上列矩阵。

对于正矩阵和逆矩阵的部分我们可以分开维护。

对于正矩阵的右乘的过程,我们可以维护每一行的和,因为每次的乘法相当于把ch位变成这一行的和,所以就直接维护就好了。

注意我们维护的是最后做完之后再乘上一个列矩阵,所以维护的时候只需要维护矩阵和矩阵乘列向量的值就好了。

对于逆矩阵的左乘,我们考虑它实际上是把当前列的第ch位减掉,而且它是对每个列除了ch行都批量的减掉,所以我们维护一下每一列的加法标记就好了。

同样我们也是要维护乘完之后再去乘上行向量的答案。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define M 11
#define N 100002
using namespace std;
const int mod=1e9+;
char s[N];
int sum[M],n,c,now[M][M],val[N],nowl[N][M],nowr[N][M],tag[M];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
int main(){
scanf("%s",s+);n=strlen(s+);
c=;
for(int i=;i<=c;++i)sum[i]=,nowr[][i]=,now[i][i]=;
nowr[][c]=;
for(int i=;i<=n;++i){
int x=s[i]-'a';
for(int j=;j<=c;++j)
val[j]=now[j][x],now[j][x]=sum[j];
for(int j=;j<=c;++j)sum[j]=(1ll*sum[j]*-val[j]+mod)%mod;
for(int j=;j<=c;++j)nowr[i][j]=(1ll*sum[j]-now[j][c]+mod)%mod;
}
nowl[][c]=;
memset(now,,sizeof(now));
for(int i=;i<=c;++i)now[i][i]=;
for(int i=;i<=n;++i){
int x=s[i]-'a';
for(int j=;j<=c;++j)val[j]=(now[x][j]+tag[j])%mod;
for(int j=;j<=c;++j)now[x][j]=(now[x][j]+val[j])%mod,tag[j]=(tag[j]-val[j]+mod)%mod;
for(int j=;j<=c;++j)nowl[i][j]=(now[c][j]+tag[j])%mod;
}
int q=rd();int l,r;
while(q--){
l=rd();r=rd();int ans=;
for(int i=;i<=c;++i)(ans+=1ll*nowr[r][i]*nowl[l-][i]%mod)%=mod;
printf("%d\n",ans);
}
return ;
}

LOJ子序列的更多相关文章

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

    [LOJ#6074]子序列(动态规划) 题面 LOJ 题解 考虑一个暴力\(dp\). 设\(f[i][c]\)表示当前在第\(i\)位,并且以\(c\)结尾的子序列个数. 那么假设当前位为\(a\) ...

  2. [科技]Loj#6564-最长公共子序列【bitset】

    正题 题目链接:https://loj.ac/p/6564 题目大意 给两个序列\(a,b\)求它们的最长公共子序列. \(1\leq n,m,a_i,b_i\leq 7\times 10^4\) 解 ...

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

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

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

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

  5. 【刷题】LOJ 6005 「网络流 24 题」最长递增子序列

    题目描述 给定正整数序列 \(x_1 \sim x_n\) ,以下递增子序列均为非严格递增. 计算其最长递增子序列的长度 \(s\) . 计算从给定的序列中最多可取出多少个长度为 \(s\) 的递增子 ...

  6. 【LOJ】#2265. 「CTSC2017」最长上升子序列

    题解 点了一个新技能叫杨表(事实上集训的时候听过,但是一直不会 这道题就是让我们找到k个不上升子序列,要求长度加和最大 我们用杨表去维护,但是由于杨表的行数可能是n的,复杂度会炸 我们只维护前\(\s ...

  7. 【LOJ】#2172. 「FJOI2016」所有公共子序列问题

    题解 听说是什么序列自动机? 我们考虑对于每个位置的串,下面拼接相同的字符时,拼接最近的一个,这样可以保证不重不漏 为了实现这个我们需要什么呢,我们需要一个链表,记录一下每个位置的下一个字符会转移到哪 ...

  8. LOJ 2172 「FJOI2016」所有公共子序列问题——序列自动机

    题目:https://loj.ac/problem/2172 在两个序列自动机上同时走,这样暴搜. 先走字典序小的字符,一边搜一边输出,就是按字典序排序的. 方案数很多,需要高精度?空间很小,要压位. ...

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

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

随机推荐

  1. JQ的.serialize()

    前面写的都是用Form表单提交,但是VUE.JS好像不能控制Form的Action. 于是就用AJAX来提交,但是跳转地址(window.location.href=)会暴露数据在url上,就直接用s ...

  2. Redis分布式队列和缓存更新

    原文链接:https://www.cnblogs.com/hua66/p/9600085.html 在使用Redis中,我们可能会遇到以下场景: 例如: 某用户向服务器中发送一个请求,服务器将用户请求 ...

  3. PHP遍历文件夹下所有文件

    不论是面试还是正常工作需要都会用到遍历文件夹下的所有文件,今天就记录一下笔记.废话不多说直接上代码: <?php /** * 遍历当前文件夹展示所有的文件和目录 */ function dirL ...

  4. arcgis api 3.x for js 入门开发系列十五台风轨迹

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  5. (详细)华为荣耀4X CHE-TL00H的usb调试模式在哪里打开的步骤

    每当我们使用PC通过数据线链上安卓手机的时候,如果手机没有开启usb开发者调试模式,PC则没能成功读到我们的手机,有时,我们使用的一些功能较强的工具好比之前我们使用的一个工具引号精灵,老版本就需要打开 ...

  6. About A Scam

    事件起因 本篇记录一个我遇到一个诈骗故事. 这两年我陆续有收到邮件,内容为有一大笔遗产我可以继承,让我提供银行卡号,身份证号相关信息. 后面邮件的内容就变为,有一笔公益款项,可以用我名义去管理,让我提 ...

  7. Linux/Ubuntu 16.04 安装编辑器 Sublime Text 3

    在ubuntu 16.04 系统上使用Sublime Text 3 编辑文本还是不错的, 先到官网下载安装包,链接:http://www.sublimetext.com/3 ,下载对应的版本,64位或 ...

  8. 编译安装redis-5.0.4

    编译安装为redis官方推荐安装方式. 本例中使用linux版本为:CentOS Linux release 7.0.1406 (Core),Basic Web Server 一.安装依赖包 yum ...

  9. redis对sorted_set进行的相关操作

    redis对sorted_set(有序集合)类型操作的相关命令以及如何在python使用这些命令 redis对sorted_set(有序集合)类型操作的命令: 命令 语法 概述 返回值 Redis Z ...

  10. vue学习初探

    一.环境的搭建安装 VS Code vue开发环境的搭建 理解vue的脚手架 合适的cnpm版本