[Codeforces 750E]New Year and Old Subsequence
2018-02-07 12:21
295 查看
Description
题库链接给出一个长度为 \(n\) 的仅包含数字的字符串。 \(q\) 次询问,每次询问该串 \([a,b]\) 段内删去几个数能够使其不含 \(2016\) 的子串,但存在 \(2017\) 的子串。
\(4\leq n\leq 200000,1\leq q\leq 200000\)
Solution
考虑朴素的 \(DP\) 。我们记 \(f_{i,j}\) 为匹配到 \(i\) 这个位置拼成 "" "2" "20" "201" "2017" 的最小花费。显然这个是 \(O(nq)\) 的。但对于每一位的转移是独立的。所以我们考虑用矩乘优化,线段树维护。
Code
//It is made by Awson on 2018.2.7 #include <bits/stdc++.h> #define LL long long #define dob complex<double> #define Abs(a) ((a) < 0 ? (-(a)) : (a)) #define Max(a, b) ((a) > (b) ? (a) : (b)) #define Min(a, b) ((a) < (b) ? (a) : (b)) #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b)) #define writeln(x) (write(x), putchar('\n')) #define lowbit(x) ((x)&(-(x))) using namespace std; const int N = 200000; void read(int &x) { char ch; bool flag = 0; for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); x *= 1-2*flag; } void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); } void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, q, a, b; char ch[N+5]; struct mat { int a[5][5]; mat() {memset(a, 127/3, sizeof(a)); } mat(int **_a) {for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++) a[i][j] = _a[i][j]; } mat operator * (const mat &b) const { mat ans; for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++) for (int k = 0; k < 5; k++) ans.a[i][j] = Min(ans.a[i][j], a[i][k]+b.a[k][j]); return ans; } }; struct Segment_tree { mat sgm[(N<<2)+5]; #define lr(x) (x<<1) #define rr(x) (x<<1|1) void build(int o, int l, int r) { if (l == r) { for (int i = 0; i < 5; i++) sgm[o].a[i][i] = 0; if (ch[l] == '2') sgm[o].a[0][0] = 1, sgm[o].a[0][1] = 0; else if (ch[l] == '0') sgm[o].a[1][1] = 1, sgm[o].a[1][2] = 0; else if (ch[l] == '1') sgm[o].a[2][2] = 1, sgm[o].a[2][3] = 0; else if (ch[l] == '7') sgm[o].a[3][3] = 1, sgm[o].a[3][4] = 0; else if (ch[l] == '6') sgm[o].a[3][3] = 1, sgm[o].a[4][4] = 1; return; } int mid = (l+r)>>1; build(lr(o), l, mid), build(rr(o), mid+1, r); sgm[o] = sgm[lr(o)]*sgm[rr(o)]; } mat query(int o, int l, int r, int a, int b) { if (a <= l && r <= b) return sgm[o]; int mid = (l+r)>>1; if (b <= mid) return query(lr(o), l, mid, a, b); if (a > mid) return query(rr(o), mid+1, r, a, b); return query(lr(o), l, mid, a, b)*query(rr(o), mid+1, r, a, b); } }T; void work() { read(n), read(q); scanf("%s", ch+1); T.build(1, 1, n); while (q--) { read(a), read(b); mat tmp = T.query(1, 1, n, a, b); writeln(tmp.a[0][4] > n ? -1 : tmp.a[0][4]); } } int main() { work(); return 0; }
相关文章推荐
- 【codeforces 750E】New Year and Old Subsequence
- CodeForces 611B - New Year and Old Property(搜索)
- codeforces-611B-New Year and Old Property
- codeforces - Goodbye2015B - New Year and Old Property
- Codeforces Good bye 2015 B. New Year and Old Property dfs 数位DP
- CodeForces 611 B. New Year and Old Property(水~)
- Codeforces Round #452 E. New Year and Old Subsequence
- 【Goodbye2015】Codeforces 611B New Year and Old Property【思维】
- codeforces 908G - New Year and Original Order 数位dp
- Codeforces Good Bye 2015 D. New Year and Ancient Prophecy 后缀数组 树状数组 dp
- Codeforces Good Bye 2017 F - New Year and Rainbow Roads
- 【CodeForces】908 D. New Year and Arbitrary Arrangement
- CodeForces 611 D. New Year and Ancient Prophecy(dp)
- codeforces 750-C. New Year and Rating(模拟)
- codeforces Good Bye 2015 C - New Year and Domino
- Codeforces Good Bye 2015 A. New Year and Days
- Codeforces-Good Bye 2017 C. New Year and Curling(计算几何)
- Codeforces_New Year and Arbitrary Arrangement
- codeforces-611C-New Year and Domino
- codeforces-Good Bye 2015-New Year and Domino