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 的,当且仅当 ...
随机推荐
- 多选ui实现单选效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- [Swift]LeetCode1032. 字符流 | Stream of Characters
Implement the StreamChecker class as follows: StreamChecker(words): Constructor, init the data struc ...
- mongo 根据对象中的某个条件来查询
假如A表有如下数据 { "id" : 1, "users_info" : [{"uid" : 10001}, {"uid" ...
- React 中的key值
在react中必须要有key值,key不是用来提升react的性能的,react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key p ...
- Hbase篇--Hbase和MapReduce结合Api
一.前述 Mapreduce可以自定义Inputforma对象和OutPutformat对象,所以原理上Mapreduce可以和任意输入源结合. 二.步骤 将结果写会到hbase中去. 2.1 Ma ...
- Python内置函数(40)——map
英文文档: map(function, iterable, ...) Return an iterator that applies function to every item of iterabl ...
- redhat 6.5安装ansible
安装epel 源: rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm 安装ansible ...
- C#计算一段代码的运行时间
第一种方法利用System.DateTime.Now: static void SubTest() { DateTime beforDT = System.DateTime.Now; //耗时巨大的代 ...
- Python爬虫入门教程 24-100 微医挂号网医生数据抓取
1. 写在前面 今天要抓取的一个网站叫做微医网站,地址为 https://www.guahao.com ,我们将通过python3爬虫抓取这个网址,然后数据存储到CSV里面,为后面的一些分析类的教程做 ...
- C# - 2017微软校园招聘笔试题 之 MS Recognition[待解决]
MS Recognition 在线提交: hihoCoder 1402 http://hihocoder.com/problemset/problem/1402 类似: OpenJudge - I:P ...