CF750E New Year and Old Subsequence solution
CF750E New Year and Old Subsequence
solution
我们用
然后就可以把
注意到后面的转移中条件如果不成立则不能转移。
接着我们发现题目把这个东西转换成了区间问题,于是乎我们就采用动态
为了方便写,我用
接着就硬解这个矩阵,解出来会长这个样子。
然后就把这个东西扔到线段树里就
code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
constexpr int inf = 0x3f3f3f3f;
struct Matrix {
int mat[5][5];
inline Matrix operator*(const Matrix &b) const {
Matrix c;
memset(c.mat, 0x3f, sizeof(c.mat));
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
for (int k = 0; k < 5; k++) c.mat[i][j] = min(mat[i][k] + b.mat[k][j], c.mat[i][j]);
return c;
}
} w[N << 2];
int n, q;
char s[N];
inline void pushup(int u) { w[u] = w[u << 1] * w[u << 1 | 1]; }
void build(int u, int L, int R) {
if (L == R) {
char c = s[L];
w[u] = (Matrix){{{c == '2', c == '2' ? 0 : inf, inf, inf, inf},
{inf, c == '0', c == '0' ? 0 : inf, inf, inf},
{inf, inf, c == '1', c == '1' ? 0 : inf, inf},
{inf, inf, inf, c == '7' || c == '6', c == '7' ? 0 : inf},
{inf, inf, inf, inf, c == '6'}}};
return;
}
int M = L + R >> 1;
build(u << 1, L, M), build(u << 1 | 1, M + 1, R);
pushup(u);
}
Matrix query(int u, int L, int R, int l, int r) {
if (L >= l && R <= r) return w[u];
int M = L + R >> 1;
if (M >= r) return query(u << 1, L, M, l, r);
if (M < l) return query(u << 1 | 1, M + 1, R, l, r);
return query(u << 1, L, M, l, r) * query(u << 1 | 1, M + 1, R, l, r);
}
int main() {
cin >> n >> q;
scanf("%s", s + 1), build(1, 1, n);
int l, r;
while (q--) {
scanf("%d %d", &l, &r);
Matrix ans = query(1, 1, n, l, r);
printf("%d\n", ans.mat[0][4] <= n ? ans.mat[0][4] : -1);
}
return 0;
}