题意

题目链接

Sol

设\(f[i][j]\)表示前\(i\)个位置中,以\(j\)为结尾的方案数。

转移的时候判断一下\(j\)是否和当前位置相同

然后发现可以用矩阵优化,可以分别求出前缀积和逆矩阵的前缀积(这题的逆矩阵炒鸡好求)

这样就可以\(n*10^3\)

发现相邻两个矩阵只有一行不同,那么其他的可以直接copy。

就可以做到\(n*10^2\)了。

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define ull unsigned long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e5 + 10, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline int add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline int mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
template <typename A, typename B> inline LL fp(A a, B p, int md = mod) {int b = 1;while(p) {if(p & 1) b = mul(b, a);a = mul(a, a); p >>= 1;}return b;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
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;
} char s[MAXN];
int N, Q, a[MAXN];
struct Ma {
int m[11][11];
Ma() {
memset(m, 0, sizeof(m));
}
void init() {
for(int i = 0; i < 10; i++) m[i][i] = 1;
}
Ma operator * (const Ma &rhs) const {
Ma ans;
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++) {
__int128 tp = 0;
for(int k = 0; k < 10; k++)
tp += 1ll * m[i][k] * rhs.m[k][j];
ans.m[i][j] = tp % mod;
}
return ans;
}
}suf[MAXN], inv[MAXN];
int solve(int l, int r) {
Ma tmp = suf[r] * inv[l - 1];
int ans = 0;
for(int i = 0; i < 10; i++) add2(ans, tmp.m[i][9]);
return (ans - 1 + mod) % mod;
}
signed main() {
// freopen("a.in", "r", stdin);
scanf("%s", s + 1);
N = strlen(s + 1);
for(int i = 1; i <= N; i++) {
a[i] = s[i] - 'a';
suf[i].init(); inv[i].init();
for(int j = 0; j < 10; j++) suf[i].m[a[i]][j] = 1;
for(int j = 0; j < 10; j++) if(j != a[i]) inv[i].m[a[i]][j] = mod - 1;
}
suf[0].init(); inv[0].init();
for(int i = 2; i <= N; i++) suf[i] = suf[i] * suf[i - 1];
for(int i = 2; i <= N; i++) inv[i] = inv[i - 1] * inv[i];
int Q = read();
while(Q--) {
int l = read(), r = read();
cout << solve(l, r) << '\n';
}
return 0;
}

loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)的更多相关文章

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

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

  2. loj#6076「2017 山东一轮集训 Day6」三元组 莫比乌斯反演 + 三元环计数

    题目大意: 给定\(a, b, c\),求\(\sum \limits_{i = 1}^a \sum \limits_{j = 1}^b \sum \limits_{k = 1}^c [(i, j) ...

  3. LOJ#6075. 「2017 山东一轮集训 Day6」重建

    题目描述: 给定一个 n个点m 条边的带权无向连通图 ,以及一个大小为k 的关键点集合S .有个人要从点s走到点t,现在可以对所有边加上一个非负整数a,问最大的a,使得加上a后,满足:s到t的最短路长 ...

  4. 「2017 山东一轮集训 Day6」子序列(矩阵快速幂)

    /* 找出了一个dp式子 是否能够倍增优化 我推的矩阵不太一样 是 1 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 2 求得逆矩阵大概就是 1 0 0 ...

  5. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  6. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  7. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  8. loj #6077. 「2017 山东一轮集训 Day7」逆序对

    #6077. 「2017 山东一轮集训 Day7」逆序对   题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...

  9. LOJ #6119. 「2017 山东二轮集训 Day7」国王

    Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...

随机推荐

  1. [Swift]LeetCode532. 数组中的K-diff数对 | K-diff Pairs in an Array

    Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in t ...

  2. CoCos2dx开发:更换导出的app名称和图标

    要处理的文件路径如下: 1.更换图标: drawable-hdpi.drawable-ldpi.drawable-mdpi三个文件夹分别代表大.小.中三个不同宽高的图片,为了应对手机的不同分辨率,来采 ...

  3. 巡风源码阅读与分析--querylogic函数

    文件位置:views/lib/QueryLogic.py Querylogic() # 搜索逻辑 def querylogic(list): query = {} if len(list) > ...

  4. HBase之Table.put客户端流程

    首先,让我们从HTable.put方法开始.由于这一节有很多方法只是简单的参数传递,我就简单略过,但是,关键的方法我还是会截图讲解,所以希望大家尽可能对照源码进行流程分析.另外,在这一节,我单单介绍p ...

  5. BBS论坛(二十三)

    23.添加板块 (1)apps/models class BoardModel(db.Model): __tablename__ = 'board' id = db.Column(db.Integer ...

  6. Guava 源码分析(Cache 原理 对象引用、事件回调)

    前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理. 文末提到了回收机制.移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析. 在开 ...

  7. es6学习笔记--模板字符串

    这几天简单看了一下深入浅出es6这本书,感觉特实用,学习了一个新特性---模板字符串在项目开发中,拼接字符串是不可缺少的,动态创建dom元素以及js操作数据都要拼接字符串,在es6出来之前,我们都通常 ...

  8. plsql中的procedure和function编程

    procedure:存储过程 eg:   create or replace procedure p   --这儿是和plsql的区别         is         cursor c      ...

  9. Java基础10:全面解读Java异常

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  10. spring cloud 配置zuul实用

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...