[Codeforces 750E]New Year and Old Subsequence
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 750E New Year and Old Subsequence - 线段树 - 动态规划
A string t is called nice if a string "2017" occurs in t as a subsequence but a string &qu ...
- Codeforces 750E New Year and Old Subsequence 线段树 + dp (看题解)
New Year and Old Subsequence 第一感觉是离线之后分治求dp, 但是感觉如果要把左边的dp值和右边的dp值合起来, 感觉很麻烦而且时间复杂度不怎么对.. 然后就gun取看题解 ...
- Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)
Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...
- 【codeforces 750E】New Year and Old Subsequence
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- New Year and Old Subsequence CodeForces - 750E (dp矩阵优化)
大意: 给定字符串, 每次询问区间[l,r]有子序列2017, 无子序列2016所需要删除的最小字符数 转移用矩阵优化一下, 要注意$(\mathbb{Z},min,+)$的幺元主对角线全0, 其余全 ...
- Educational Codeforces Round 32:E. Maximum Subsequence(Meet-in-the-middle)
题目链接:E. Maximum Subsequence 用了一个Meet-in-the-middle的技巧,还是第一次用到这个技巧,其实这个技巧和二分很像,主要是在dfs中,如果数量减小一半可以节约很 ...
- Codeforces Round #646 (Div. 2) B. Subsequence Hate(前缀和)
题目链接:https://codeforces.com/contest/1363/problem/B 题意 可以将 $01$ 串中的 $0$ 变为 $1$.$1$ 变为 $0$,问至少需要变换多少字符 ...
- Codeforces 750E 线段树DP
题意:给你一个字符串,有两种操作:1:把某个位置的字符改变.2:询问l到r的子串最少需要删除多少个字符,使得这个子串含有2017子序列,并且没有2016子序列? 思路:线段树上DP,我们设状态0, 1 ...
- Codeforces Round #646 (Div. 2) B. Subsequence Hate (思维,前缀和)
题意:给你一个只含有\(0\)和\(1\)的字符串,每次操作可以将\(0\)改成\(1\)或\(1\)改成\(0\),问最少操作多少次,使得子序列中不含有\(010\)和\(101\). 题解:仔细想 ...
随机推荐
- Mybash的实现
Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 背景知识 1. fork 使用 ...
- HDFS之RPC机制
- sql 多条记录插入
--多条记录插入,用逗号分开值. INSERT dbo.studentinfor ( id, name, class, age, hpsw ) ', -- id - nvarchar(50) N'te ...
- H5 FormData对象的作用及用法
JS: function uploadFileAndParam() { var url = "http://localhost:42561/api/upload/UploadPost&quo ...
- android studio 何如修改报名
1. 重命名办法,网上很多见 2. 对于需要重新修改包名的级别的 a. 修改package 和 gradle 的包名,对应一致. b. 修改R 所在包名,使用crtl+n修改R文件的路径 c. 手动首 ...
- 复习HTML+CSS(2)
n 项目符号嵌套编号思路 标签的内容(文本.项目符号.表格.图片等)必须放在最底层标记中. n 图片标记(行内元素,单边标记) l 语法:<img 属性 = "值"&g ...
- Python/Django(CBV/FBV/ORM操作)
Python/Django(CBV/FBV/ORM操作) CBV:url对应的类(模式) ##====================================CBV操作============ ...
- POJ-2586 Y2K Accounting Bug贪心,区间盈利
题目链接: https://vjudge.net/problem/POJ-2586 题目大意: MS公司(我猜是微软)遇到了千年虫的问题,导致数据大量数据丢失.比如财务报表.现在知道这个奇特的公司每个 ...
- 1.4WEB API 路由配置及参数传输
在没有添加路由时,webapi 的访问比较恶心,访问的时候是没有接口方法的.如果定义了同样参数的方法,它就傻傻的分不清的,为了解决这个问题,我们加上路由吧. 这是生成的api帮助文档列表,可以看到下面 ...
- js 常用数组和字符串方法
javascript数组与字符串常用方法总结 最近在梳理js的基础,首先从数组和字符串开始. string 常用方法: 1.substring(start开始位置的索引,end结束位置索引) 截取的位 ...