time limit per test3 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

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”.

【题目链接】:http://codeforces.com/contest/750/problem/E

【题解】

    merge矩阵(dp)+线段树;
m[i][j]表示从状态i->j转移的花费;
0表示什么都没有
1表示出现了2
2表示出现了20
3表示出现了201
4表示出现了2017
出现了2,20,则遇到6的时候我么可以不用管;
但是如果出现了201或2017,然后又遇到了6,则我们需要把这个6删掉;
for (i = 0;i <= 4;i++)//除了遇到2,0,1,6,7这5个特别的数字之外,
m[i][i] = 0;//遇到的时候状态都不会变;所以不用花费(操作);
if (ch == '2')
{
m[0][0] = 1;//什么都没有->什么都没有,删掉这个2
m[0][1] = 0;//什么都没有->出现了2,花费变成0
//注意这里m[1][1] = 0,表示从出现了一个2到出现了一个2可以不用删掉任何东西,因为加上一个2也无妨,下面的解释就省略了,希望大家能看得明白.
}
if (ch=='0')
{
m[1][1] = 1 ;//出现了一个2->出现了一个2,则把0删掉
m[1][2] = 0;//从出现一个2->出现了20,因为当前就是0,所以什么都不用加
}
if (ch=='1')
{
ma[2][2] = 1;//出现了20->出现了20,则把1删掉
ma[2][3] = 0;//出现了20->出现了201,因为刚好遇到一个1则什么都不加
}
if (ch=='7')
{
m[3][3] = 1;//出现了201->出现了201,则把遇到的7删掉
m[3][4] = 0;//出现了201->出现了2017,刚好遇到7,则什么都不做
}
if (ch=='6')
{
a[3][3] = 1;//出现了201->出现了数字6,则一定要把6删掉,不然无法满足题意
a[4][4] = 1;//出现了2017->出现了数字6,则也一定要把6删掉.
}
线段树加一个合并操作就好;
那个合并的操作和floyd算法类似;
最后输出m[0][4];表示从什么都没有然后出现"2017"

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int MAXN = 2e5+10;
const int INF = 7e8;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); struct abc
{
int m[5][5];
friend abc operator * (abc a,abc b)
{
abc d;
rep1(i,0,4)
rep1(j,0,4)
{
d.m[i][j] = INF;
rep1(k,0,4)
d.m[i][j] = min(d.m[i][j],a.m[i][k]+b.m[k][j]);
}
return d;
}
}; int n,q;
abc a[MAXN*4];
char s[MAXN]; void build(int l,int r,int rt)
{
if (l==r)
{
char ch = s[l];
rep1(i,0,4)
rep1(j,0,4)
a[rt].m[i][j] = (i==j)?0:INF;
if (ch == '2')
{
a[rt].m[0][0] = 1;
a[rt].m[0][1] = 0;
}
if (ch=='0')
{
a[rt].m[1][1] = 1;
a[rt].m[1][2] = 0;
}
if (ch=='1')
{
a[rt].m[2][2] = 1;
a[rt].m[2][3] = 0;
}
if (ch=='7')
{
a[rt].m[3][3] = 1;
a[rt].m[3][4] = 0;
}
if (ch=='6')
{
a[rt].m[3][3] = 1;
a[rt].m[4][4] = 1;
}
return;
}
int m = (l+r)>>1;
build(lson);build(rson);
a[rt] = a[rt<<1]*a[rt<<1|1];
} abc query(int L,int R,int l,int r,int rt)
{
if (L<=l && r <= R)
return a[rt];
int m = (l+r)>>1;
abc temp1,temp2;
bool f1 = 0,f2 = 0;
if (L <= m)
{
temp1 = query(L,R,lson);
f1 = 1;
}
if (m < R)
{
temp2 = query(L,R,rson);
f2 = 1;
}
if (f1&&f2)
return temp1*temp2;
if (f1)
return temp1;
if (f2)
return temp2;
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);rei(q);
scanf("%s",s+1);
build(1,n,1);
rep1(i,1,q)
{
int L,R;
rei(L);rei(R);
int ans = query(L,R,1,n,1).m[0][4];
if (ans>=INF)
puts("-1");
else
cout << ans << endl;
}
return 0;
}

最新文章

  1. 从零开始山寨Caffe&#183;壹:仰望星空与脚踏实地
  2. linux修改时区为中国时区(北京)
  3. 制作web字体:CSS3 @font-face
  4. coreseek实战(二):windows下mysql数据源部分配置说明
  5. A.2 Main
  6. POJ 3662
  7. sys.default_constraints
  8. SQLServer加入域后无法远程连接
  9. Android-用webservice连接sqlserver数据库
  10. 2013 南京邀请赛 C count the carries
  11. javascript笔记整理(变量作用域)
  12. opencv BP神经网络使用过程
  13. 6. Java 加解密技术系列之 3DES
  14. MachineLN博客目录
  15. Java的家庭记账本程序(B)
  16. Android Stuido 方法参数 p0,p1
  17. windows10系统下安装pygame
  18. Swagger使用
  19. 只有mdf文件的恢复方法
  20. HDU 3038 - How Many Answers Are Wrong - [经典带权并查集]

热门文章

  1. 【程序猿笔试面试复习】之中的一个 网络与通信篇(一) 几大网络模型:OSI、TCP/IP、B/S与C/S、MVC结构
  2. 用PHP 去掉所有html标签里的部分属性
  3. 如何使用echo.js实现图片的懒加载(整理)
  4. 分析器错误消息: 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分
  5. Mycat快速入门
  6. javascript中的事件问题的总结
  7. ajax日期參数格式问题
  8. QWaitCondition 的正确使用方法(通过 mutex 把有严格时序要求的代码保护起来,同时把 wakeAll() 也用同一个 mutex 保护起来)
  9. UVA 11280 - Flying to Fredericton SPFA变形
  10. WCF 设计和实现服务协定(01)