题目链接

思路

首先考虑暴力\(dp\)

用\(f[i][j]\)表示前\(i\)个字符,以\(j\)这个字符结尾的本质不同的字符串个数。

然后就有如下的转移

\(if(s_i==j)\)

$$f_{ij}=\sum\limits_{i=1}^9f_{i-1j} + 1$$

\(else\)

$$f_{ij}=f_{i-1j}$$

然后就尝试一下用矩阵转移

对于第\(i\)位置,设一个\(10 \times 10\)的单位矩阵,将\(s_i\)这一列全都是\(1\)。

为什么是\(10 \times 10\)而不是\(9\times9\)呢?

因为第一个转移里面有个\(+1\)

然后对于每次询问,都将初始的\(1 \times 10\)的矩阵的第\(s_{l-1}\)位和第\(10\)位设成\(1\),其他的都是\(0\)。

然后依次乘上\(l\)~\(r\)的矩阵即可。

然后优化

可以发现,用矩阵转移更慢了。

别慌,我们只要想办法快速的将\(l\)~\(r\)内的矩阵乘起来不就行了。

对于这\(n\)个矩阵先处理一个前缀和。然后只要用前\(r\)个矩阵去除以前\(l - 1\)个矩阵就行了。

怎么除呢??

我们把每个矩阵的逆矩阵也求个前缀和就行了。

PS: 矩阵乘法不满足交换律,注意矩阵相乘的顺序。

代码

/* @Author: wxyww
* @Date: 2019-03-28 20:43:54
* @Last Modified time: 2019-03-29 13:53:49
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100010,mod = 1e9 + 7;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct node {
int a[11][11];
int n,m;
node() {
memset(a,0,sizeof(a));
}
node(int x) {
n = m = x;
memset(a,0,sizeof(a));
for(int i = 1;i <= x;++i) a[i][i] = 1;
}
node(int x,int y) {
n = x,m = y;
memset(a,0,sizeof(a));
}
}tmp1[N],tmp2[N];
char S[N];
int n,s[N];
node operator * (const node &A,const node &B) {
int n = A.n,m = B.n,K = A.m;
node ret(n,m);
for(int k = 1;k <= K;++k) {
for(int i = 1;i <= n;++i) {
for(int j = 1;j <= m;++j) {
ret.a[i][j] += 1ll * A.a[i][k] * B.a[k][j] % mod;
ret.a[i][j] %= mod;
}
}
}
return ret;
}
void pre() {
tmp1[0] = tmp2[0] = node(10);
for(int i = 1;i <= n;++i) {
int k = s[i];
tmp1[i] = tmp2[i] = node(10);
for(int j = 1;j <= 10;++j) tmp1[i].a[j][k] = 1,tmp2[i].a[j][k] = mod - 1;
tmp2[i].a[k][k] = 1;
tmp1[i] = tmp1[i] * tmp1[i - 1];
tmp2[i] = tmp2[i - 1] * tmp2[i];
}
}
int main() {
scanf("%s",S + 1);
n = strlen(S + 1);
for(int i = 1;i <= n;++i) s[i] = S[i] - 'a' + 1;
pre();
int m = read();
while(m--) {
node ans(1,10);
int l = read(),r = read();
ans.a[1][10] = 1;
ans = ans * tmp1[r] * tmp2[l - 1];
int anss = 0;
for(int i = 1;i <= 9;++i) anss += ans.a[1][i],anss %= mod;
printf("%d\n",anss);
}
return 0;
} */

loj6074 子序列的更多相关文章

  1. 【LOJ6074】【2017 山东一轮集训 Day6】子序列 DP

    题目描述 有一个由前 \(m\) 个小写字母组成的串 \(S\),有 \(q\) 个询问,每次给你 \(l,r\),问你 \(S_{l\ldots r}\) 有多少个非空子序列. \(m=9,n=\l ...

  2. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  3. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  4. [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

  5. [LeetCode] Is Subsequence 是子序列

    Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...

  6. [LeetCode] Wiggle Subsequence 摆动子序列

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...

  7. [LeetCode] Increasing Triplet Subsequence 递增的三元子序列

    Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...

  8. [LeetCode] Distinct Subsequences 不同的子序列

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  9. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

随机推荐

  1. vue 模板template

    入门 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8& ...

  2. 前端入门24-响应式布局(BootStrap)

    声明 本篇内容摘抄自以下两个来源: BootStrap中文网 感谢大佬们的分享. 正文-响应式布局(BootStrap) 这次想来讲讲一个前端开发框架:BootStrap BootStrap 目前已经 ...

  3. ArcPy 创建图层空间索引

    使用Python脚本进行图层的空间索引的创建. 附上Python代码: # -*- coding: utf-8 -*- # nightroad import sys import arcpy relo ...

  4. Glide的 java.lang.RuntimeException: Expected instanceof GlideModule, but found:X.GlideModule@2e4554f

    问题一 在添加过混淆规则后,App打包的时候,发现报错了 java.lang.RuntimeException: Expected instanceof GlideModule, but found: ...

  5. There is already an object named '#xxxx' in the database.

    这个案例是前几天同事遇到的一个案例,在存储过程中"删除"了一个临时表,然后重新创建这个临时表时遇到"There is already an object named 'x ...

  6. nginx预防常见攻击

    目录 nginx防止DDOS攻击 概述 攻击手段 配置 限制请求率 限制连接的数量 关闭慢连接 设置 IP 黑名单 设置IP白名单 小站点解决方案 nginx防止CC攻击 概述 主动抑制方法 应用举例 ...

  7. SCOI2019酱油记

    这玩意儿咕了--留坑待填

  8. WPF效果(GIS三维续篇)

    去年这个时候简单的摸索了一下三维的GIS相关的东西,也就是仅仅玩耍了一把,这次来点真正用的上的干货效果效果: 1.加载自定义百度样式的瓦片效果 2.加载自定义百度样式的缩放效果 3.快速手动进去咱的大 ...

  9. C# .NET 0配置使用Wcf(半成品)

    设计原则:万物皆对象 背景:微软提供了一套强大的通信框架Wcf,了解请看百度百科:ttps://baike.baidu.com/item/Wcf/7374854?fr=aladdin 虽然这套通信框架 ...

  10. nextInt()和nextLine()一起使用时的注意点

    问题原因:nextLine()会把nextInt(),next(),nextDouble(),nextFloat()的结束换行符作为字符串读入,进而不需要从键盘输入字符串nextLine便已经转向了下 ...