loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)
题意
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)的更多相关文章
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- loj#6076「2017 山东一轮集训 Day6」三元组 莫比乌斯反演 + 三元环计数
题目大意: 给定\(a, b, c\),求\(\sum \limits_{i = 1}^a \sum \limits_{j = 1}^b \sum \limits_{k = 1}^c [(i, j) ...
- LOJ#6075. 「2017 山东一轮集训 Day6」重建
题目描述: 给定一个 n个点m 条边的带权无向连通图 ,以及一个大小为k 的关键点集合S .有个人要从点s走到点t,现在可以对所有边加上一个非负整数a,问最大的a,使得加上a后,满足:s到t的最短路长 ...
- 「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 ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- loj #6077. 「2017 山东一轮集训 Day7」逆序对
#6077. 「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...
- LOJ #6119. 「2017 山东二轮集训 Day7」国王
Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...
随机推荐
- [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 ...
- CoCos2dx开发:更换导出的app名称和图标
要处理的文件路径如下: 1.更换图标: drawable-hdpi.drawable-ldpi.drawable-mdpi三个文件夹分别代表大.小.中三个不同宽高的图片,为了应对手机的不同分辨率,来采 ...
- 巡风源码阅读与分析--querylogic函数
文件位置:views/lib/QueryLogic.py Querylogic() # 搜索逻辑 def querylogic(list): query = {} if len(list) > ...
- HBase之Table.put客户端流程
首先,让我们从HTable.put方法开始.由于这一节有很多方法只是简单的参数传递,我就简单略过,但是,关键的方法我还是会截图讲解,所以希望大家尽可能对照源码进行流程分析.另外,在这一节,我单单介绍p ...
- BBS论坛(二十三)
23.添加板块 (1)apps/models class BoardModel(db.Model): __tablename__ = 'board' id = db.Column(db.Integer ...
- Guava 源码分析(Cache 原理 对象引用、事件回调)
前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理. 文末提到了回收机制.移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析. 在开 ...
- es6学习笔记--模板字符串
这几天简单看了一下深入浅出es6这本书,感觉特实用,学习了一个新特性---模板字符串在项目开发中,拼接字符串是不可缺少的,动态创建dom元素以及js操作数据都要拼接字符串,在es6出来之前,我们都通常 ...
- plsql中的procedure和function编程
procedure:存储过程 eg: create or replace procedure p --这儿是和plsql的区别 is cursor c ...
- Java基础10:全面解读Java异常
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- spring cloud 配置zuul实用
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...