这道题和一道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的更多相关文章

  1. 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)

    题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...

  2. ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

    ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...

  3. ACM-ICPC 2019南昌网络赛F题 Megumi With String

    ACM-ICPC 南昌网络赛F题 Megumi With String 题目描述 给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str ...

  4. 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)} ...

  5. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

  6. 2019南昌网络赛-M(二分)

    题目链接:https://nanti.jisuanke.com/t/38232 题意:给定字符串s(长度<=1e5),然后N组样例(N<=1e5),每组输入一个字符串t判断t是否为s的字串 ...

  7. 2019南昌网络赛H The Nth Item(打表找询问循环节 or 分段打表)

    https://nanti.jisuanke.com/t/41355 思路 从fib循环节入手,\(O(1e7log(1e9))\),tle 因为只需要输出所有询问亦或后的结果,所以考虑答案的循环节, ...

  8. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树

    I. Yukino With Subinterval 题目链接: Problem Descripe Yukino has an array \(a_1, a_2 \cdots a_n\). As a ...

  9. 2019南昌网络赛 J Distance on the tree 主席树+lca

    题意 给一颗树,每条边有边权,每次询问\(u\)到\(v\)的路径中有多少边的边权小于等于\(k​\) 分析 在树的每个点上建\(1​\)到\(i​\)的权值线段树,查询的时候同时跑\(u,v,lca ...

随机推荐

  1. 大二上学期Javaweb阶段性学习总结

    本学期主要学了h5,css3,js,Java,SQL server数据库基本操作等相关知识,学会了简单web系统的制作. 这个学期总的来说学到了很多东西. 前期Java学习因为有了暑期学习及pta上5 ...

  2. DataGridView 调整列顺序为设计的顺序

    设置: dataGridView1.AutoGenerateColumns = false;

  3. 题解 AT859 【元素の系統名】

    题目传送门. 介绍一种使用string字符串的方法. \(string\)是\(C++\).\(java\).\(VB\)等编程语言中的字符串,字符串是一个特殊的对象,属于引用类型. \(C++\)标 ...

  4. 番外:可刷新PDB的管理操作(如何切换PDB Switching Over)

    基于版本:19c (12.2.0.3) AskScuti 主题:可刷新PDB如何进行切换操作 内容说明:本篇延续如何克隆可刷新的PDB(Refreshable PDB)一文,进行切换实验. 具体请参考 ...

  5. SpringBoot整合WEB开发--(六)CROS支持

    简介: CROS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的为了解决前端的跨域请求,在JavaEE开发中,最常见的前端跨域请求解决方案 ...

  6. Django文件夹

    Django文件 App文件夹 migrations文件 生成models创建表的翻译语句 telemplatetags文件夹 telemplatetags文件夹下的文件专门用来创建自定义标签.自定义 ...

  7. PCB主线布线规范—高速线之DDR2

    一.DDR2时钟线走线规则a)时钟线包括 MEM_CLKOUT#0.MEM_CLKOUT0.MEM_CLKOUT#1.MEM_CLKOUT1,MEM_CLKOUT#2.MEM_CLKOUT2: MEM ...

  8. 5G套餐资费或为199元至599元,高昂价格会阻碍大众使用热情吗?

    近段时间,运营商各种谜一般的操作让其走上舆论的风口浪尖,成为人们口诛笔伐的对象.比如在前段时间,运营商相继宣布要取消"达量降速版畅享套餐",对用户的权益造成巨大冲击,引发了网络热议 ...

  9. Python 入门【一】Python 初识及学习资料

    Python 初识及学习路线: CodeCademy Python 在线教学: 廖雪峰 Python 2.7 教程: 廖雪峰 Python 3.0 教程: Python 官方文档(2.7~3.7:英文 ...

  10. MYSQL入门总结

    创建数据库及创建表 create schema/database ttest(名字); //创建数据库 create table ttest(建好的数据库名字).new_table(表名字) ( a ...