2019南昌网络赛 hello 2019
这道题和一道2017,2016的类似。
A string t is called nice if a string “2017” occurs in t as a subsequence but a string “2016” doesn’t occur in t as a subsequence. For example, strings “203434107” and “9220617” are nice, while strings “20016”, “1234” and “20167” aren’t nice.
The ugliness of a string is the minimum possible number of characters to remove, in order to obtain a nice string. If it’s impossible to make a string nice by removing characters, its ugliness is - 1.
Limak has a string s of length n, with characters indexed 1 through n. He asks you q queries. In the i-th query you should compute and print the ugliness of a substring (continuous subsequence) of s starting at the index ai and ending at the index bi (inclusive).
Input
The first line of the input contains two integers n and q (4 ≤ n ≤ 200 000, 1 ≤ q ≤ 200 000) — the length of the string s and the number of queries respectively.
The second line contains a string s of length n. Every character is one of digits ‘0’–‘9’.
The i-th of next q lines contains two integers ai and bi (1 ≤ ai ≤ bi ≤ n), describing a substring in the i-th query.
Output
For each query print the ugliness of the given substring.
Examples
Input
8 3
20166766
1 8
1 7
2 8
Output
4
3
-1
Input
15 5
012016662091670
3 4
1 14
4 15
1 13
10 15
Output
-1
2
1
-1
-1
Input
4 2
1234
2 4
1 2
Output
-1
-1
Note
In the first sample:
In the first query, ugliness(“20166766”) = 4 because all four sixes must be removed.
In the second query, ugliness(“2016676”) = 3 because all three sixes must be removed.
In the third query, ugliness(“0166766”) = - 1 because it’s impossible to remove some digits to get a nice string.
In the second sample:
In the second query, ugliness(“01201666209167”) = 2. It’s optimal to remove the first digit ‘2’ and the last digit ‘6’, what gives a string “010166620917”, which is nice.
In the third query, ugliness(“016662091670”) = 1. It’s optimal to remove the last digit ‘6’, what gives a nice string “01666209170”.
要是以前做过这道题就好了。。南昌的题目和这道题换汤不换药,改改顺序就好了。。
如果是单次询问的话,就直接区间dp做就好了。但是这次是多次查询,我们就需要利用数据结构了。区间查询,线段树给上。
我们定义0,1,2,3,4为"",2,20,201,2017的状态。对于每个状态用矩阵表示:
a[i][j]代表着从状态i转移到状态j所需要花费的价值。一开始把对角线上初始化为0,其余的变为inf。
假如当前位置是2的话,那么状态转移矩阵就变为:
从"“变为2不需要花费价值,但是从”“到”“需要花费价值为1,因为保持”"需要删除2。0,1,7是一样的。
但是到6的时候,保持201到201需要删除6,花费价值为1。因为不能出现2016,所以从2017转移也需要删除一个价值。
因为要求最小价值,所以类似于floyed矩阵加法:
————————————————
版权声明:本文为CSDN博主「starlet_kiss」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/starlet_kiss/article/details/100694910
代码如下:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; const int maxx=2e5+;
struct node{
int a[][];
node operator+(const node &b)const//重载加法
{
node c;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
c.a[i][j]=inf;
for(int k=;k<;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
}
}
return c;
}
}p[maxx<<];
char s[maxx];
int n,m; inline void pushup(int cur)
{
p[cur]=p[cur<<]+p[cur<<|];
}
inline void build(int l,int r,int cur)
{
if(l==r)
{
for(int i=;i<;i++)for(int j=;j<;j++) p[cur].a[i][j]=(i==j)?:inf;
if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
return ;
}
int mid=l+r>>;
build(l,mid,cur<<);
build(mid+,r,cur<<|);
pushup(cur);
}
inline node query(int L,int R,int l,int r,int cur)
{
if(l<=L&&R<=r) return p[cur];
int mid=L+R>>;
if(r<=mid) return query(L,mid,l,r,cur<<);
else if(l>mid) return query(mid+,R,l,r,cur<<|);
else return query(L,mid,l,mid,cur<<)+query(mid+,R,mid+,r,cur<<|);
}
int main()
{
int l,r;
while(~scanf("%d%d",&n,&m))
{
scanf("%s",s+);
build(,n,);
while(m--)
{
scanf("%d%d",&l,&r);
node ans=query(,n,l,r,);
if(ans.a[][]==inf) printf("-1\n");
else printf("%d\n",ans.a[][]);
}
}
return ;
}
————————————————
版权声明:本文为CSDN博主「starlet_kiss」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/starlet_kiss/article/details/100694910
南昌的这道题因为是9102和8102的区别,出现的位置是在第一个,我们把原来的字符串倒一下,把询问区间换成倒置之后的区间就好了。
代码如下:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; const int maxx=2e5+;
struct node{
int a[][];
node operator+(const node &b)const
{
node c;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
c.a[i][j]=inf;
for(int k=i;k<;k++){
if(k>j) continue;
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
}
}
}
return c;
}
}p[maxx<<];
char s[maxx],ss[maxx];
int n,m; inline void pushup(int cur)
{
p[cur]=p[cur<<]+p[cur<<|];
}
inline void build(int l,int r,int cur)
{
if(l==r)
{
for(int i=;i<;i++)for(int j=;j<;j++) p[cur].a[i][j]=(i==j)?:inf;
if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
else if(s[l]=='') p[cur].a[][]=,p[cur].a[][]=;
return ;
}
int mid=l+r>>;
build(l,mid,cur<<);
build(mid+,r,cur<<|);
pushup(cur);
}
inline node query(int L,int R,int l,int r,int cur)
{
if(l<=L&&R<=r) return p[cur];
int mid=L+R>>;
if(r<=mid) return query(L,mid,l,r,cur<<);
else if(l>mid) return query(mid+,R,l,r,cur<<|);
else return query(L,mid,l,mid,cur<<)+query(mid+,R,mid+,r,cur<<|);
}
int main()
{
int l,r;
while(~scanf("%d%d",&n,&m))
{
scanf("%s",ss+);
for(int i=;i<=n;i++) s[i]=ss[n-i+];
build(,n,);
while(m--)
{
scanf("%d%d",&l,&r);
node ans=query(,n,n-r+,n-l+,);
if(ans.a[][]==inf) printf("-1\n");
else printf("%d\n",ans.a[][]);
}
}
return ;
}
2019南昌网络赛 hello 2019的更多相关文章
- 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)
题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...
- ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval
ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...
- ACM-ICPC 2019南昌网络赛F题 Megumi With String
ACM-ICPC 南昌网络赛F题 Megumi With String 题目描述 给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str ...
- 2019南昌网络赛G. tsy's number
题意:\(\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n\frac{\phi(i)*\phi(j^2)*\phi(k^3)}{\phi(i)*\phi(j)*\phi(k)} ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- 2019南昌网络赛-M(二分)
题目链接:https://nanti.jisuanke.com/t/38232 题意:给定字符串s(长度<=1e5),然后N组样例(N<=1e5),每组输入一个字符串t判断t是否为s的字串 ...
- 2019南昌网络赛H The Nth Item(打表找询问循环节 or 分段打表)
https://nanti.jisuanke.com/t/41355 思路 从fib循环节入手,\(O(1e7log(1e9))\),tle 因为只需要输出所有询问亦或后的结果,所以考虑答案的循环节, ...
- 2019南昌网络赛 I. Yukino With Subinterval 树状数组套线段树
I. Yukino With Subinterval 题目链接: Problem Descripe Yukino has an array \(a_1, a_2 \cdots a_n\). As a ...
- 2019南昌网络赛 J Distance on the tree 主席树+lca
题意 给一颗树,每条边有边权,每次询问\(u\)到\(v\)的路径中有多少边的边权小于等于\(k\) 分析 在树的每个点上建\(1\)到\(i\)的权值线段树,查询的时候同时跑\(u,v,lca ...
随机推荐
- BZOJ的思维题
5085:最大 给你一个n×m的矩形,要你找一个子矩形,价值为左上角左下角右上角右下角这四个数的最小值,要你最大化矩形 的价值. 关键点是要想到把这些值排序 值从小到大考虑,比如说现在最小的值是(x1 ...
- 机器学习作业(三)多类别分类与神经网络——Matlab实现
题目太长了!下载地址[传送门] 第1题 简述:识别图片上的数字. 第1步:读取数据文件: %% Setup the parameters you will use for this part of t ...
- 机器学习作业(二)逻辑回归——Python(numpy)实现
题目太长啦!文档下载[传送门] 第1题 简述:实现逻辑回归. 此处使用了minimize函数代替Matlab的fminunc函数,参考了该博客[传送门]. import numpy as np imp ...
- RN开发-JSX基础语法
1.环境 react.js react-dom.js browser.min.js(解码器) 2.载入方式 内联.外联 ...
- vue 项目初始化
初始化 vue init webpack-simple myproject 安裝 npm install 运行 npm run dev 访问地址 http://localhost:8080/ 安装we ...
- 3.获取某天的最大时间和最小时间,使用Calendar
if (taxTraySummaryListDTO.getStartDate() != null) { Calendar cal = Calendar.getInstance(); cal.setTi ...
- 10.pandas的替换和部分替换(replace)
在处理数据的时候,很多时候会遇到批量替换的情况,如果一个一个去修改效率过低,也容易出错.replace()是很好的方法. 源数据 1.替换全部或者某一行 replace的基本结构是:df.repl ...
- [HNOI2017] 礼物 - 多项式乘法FFT
题意:给定两个 \(n\) 元环,环上每个点有权值,分别为 \(x_i, y_i\).定义两个环的差值为 \[\sum_{i=0}^{n-1}{(x_i-y_i)^2}\] 可以旋转其中的一个环,或者 ...
- 修改oracle数据库用户名和密码
第一步:连接数据库 使用ssh工具以root身份连接服务器, 然后切换到oracle用户:su - oracle(回车) 使用sqlplus连接数据库:sqlplus /nolog(回车) 以管理员身 ...
- Oracle的物理结构的三种文件
.dbf数据文件,是用于存储数据库数据的文件,例如表中的记录,索引,数据字典信息等,可以通过系统数据字典DBA_DATA_FILES查看相关信息.与逻辑角度的表空间(并不是真正的文件)对应,一个表空间 ...