A digital string is "good": when it contains a subsequence 91029102 and does not contain a subsequence 81028102.
The bad value of a string is defined as how many characters are to remove at least, so that the string satisfies the "good" property. Output -1
if the string cannot satisfy the "good" property by removing some characters (0 or maybe more).
Input
The first line contains two integers n, Qn,Q(1\leq n,Q\leq2*10^5)(1≤n,Q≤2∗105). Where nn is the length of the string and QQ is the number of queries.
The second line contains a string ss that consists entirely of decimal numbers.
The next QQ line, each line contains two integers l, rl,r(1\leq l\leq r\leq n)(1≤l≤r≤n), denoting a query.
Output
For each query, output an answer which is the bad value of the substring s_ls_{l+1} \cdots s_rslsl+1⋯sr from ss.
样例输入复制
8 3 88988102 1 8 2 8 1 7
样例输出复制
4 3 -1
题目大意:给出一个字符串,每次查询区间只包含9102而不包含8102至少要删去多少字符(这里的包含是指子序列包含)。
解题思路:如果没有对区间查询的话,应该是个dp,由于是对区间的查询,并且可以分治,所以就考虑线段树转移dp了。
详情:TP
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e5+5;
const int inf = 0x3f3f3f3f;
struct node
{
int a[5][5];
void init(){memset(a,inf,sizeof(a));}
}t[N*4];
node ans;
node Merge(node le,node ri)
{
node tmp;
tmp.init();
for(int i=0;i<5;i++)
{
for(int j=i;j<5;j++)
{
for(int k=i;k<=j;k++)
{
tmp.a[i][j]=min(tmp.a[i][j],le.a[i][k]+ri.a[k][j]);
}
}
}
return tmp;
}
char s[N];
int num[N];
void build(int rt,int l,int r)
{
if(l==r)
{
t[rt].init();
for(int i=0;i<5;i++)t[rt].a[i][i]=0;
if(num[l]==2){t[rt].a[0][0]=1;t[rt].a[0][1]=0;}
if(num[l]==0){t[rt].a[1][2]=0;t[rt].a[1][1]=1;}
if(num[l]==1){t[rt].a[2][2]=1;t[rt].a[2][3]=0;}
if(num[l]==9){t[rt].a[3][3]=1;t[rt].a[3][4]=0;}
if(num[l]==8){t[rt].a[3][3]=1;t[rt].a[4][4]=1;}
return ;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
t[rt]=Merge(t[rt<<1],t[rt<<1|1]);
}
void query(int rt,int l,int r,int ql,int qr)
{
if(l>=ql && r<=qr)
{
if(l==ql) ans=t[rt];
else ans=Merge(ans,t[rt]);
return ;
}
int m=(l+r)>>1;
if(ql<=m) query(rt<<1,l,m,ql,qr);
if(qr>m) query(rt<<1|1,m+1,r,ql,qr);
}
int pos[N];
int main()
{
int n,m;
cin>>n>>m;
scanf("%s",s+1);
for(int i=1;i<=n;i++)num[i]=s[n-i+1]-'0';
build(1,1,n);
int now=n;
for(int i=1;i<=(n+(n%2))/2;i++)
{
pos[i]=now;
pos[now]=i;
now--;
}
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
ans.init();
query(1,1,n,pos[r],pos[l]);
printf("%d\n",ans.a[0][4]==inf?-1:ans.a[0][4]);
}
}