火山哥与打铁传说
我
们
发
现
,
其
实
鱼
可
以
看
成
括
号
序
列
,
其
中
01
,
11
均
可
配
对
,
但
显
然
01
更
优
,
所
以
我
们
优
先
配
01
,
然
后
再
配
11
我们发现,其实鱼可以看成括号序列,其中01,11均可配对,但显然01更优,所以我们优先配01,然后再配11
我们发现,其实鱼可以看成括号序列,其中01,11均可配对,但显然01更优,所以我们优先配01,然后再配11
统
计
答
案
时
,
我
们
先
看
剩
下
的
1
能
不
能
取
完
大
鱼
,
不
能
的
话
将
11
拆
开
,
一
次
配
两
条
鱼
统计答案时,我们先看剩下的1能不能取完大鱼,不能的话将11拆开,一次配两条鱼
统计答案时,我们先看剩下的1能不能取完大鱼,不能的话将11拆开,一次配两条鱼
如
果
还
是
不
行
,
就
拆
01
,
一
次
配
1
条
鱼
如果还是不行,就拆01,一次配1条鱼
如果还是不行,就拆01,一次配1条鱼
还
是
不
行
,
就
没
鱼
了
,
配
不
了
还是不行,就没鱼了,配不了
还是不行,就没鱼了,配不了
注
意
点
:
11
拆
开
可
以
配
两
条
鱼
注意点:11拆开可以配两条鱼
注意点:11拆开可以配两条鱼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+5;
int n,q,dy[N],xy[N],sum[N],lst[N],tmp[N],tmplst[N];
char s[N];
ll read(){
char c=getchar();ll ans=0,f=1;
while('0'>c||c>'9') {if(c=='-') f*=-1;c=getchar();}
for(;'0'<=c&&c<='9';c=getchar()) ans=(ans<<3)+(ans<<1)+c-'0';
return ans*f;
}
int main(){
n=read(),q=read();
scanf("%s",(s+1));
for(int i=1;i<=n;i++){
tmp[i]+=tmp[i-1];
tmplst[i]+=tmplst[i-1];
dy[i]+=dy[i-1];
xy[i]+=xy[i-1];
lst[i]+=lst[i-1];
sum[i]+=sum[i-1];
if(s[i]=='0')
{
xy[i]++;
}
if(s[i]=='1'){
dy[i]++;
if(xy[i]){
sum[i]++;
xy[i]--;
continue;
}
else if(tmplst[i]){
tmplst[i]--,tmp[i]++;lst[i]++;//
continue;
}
else {
tmplst[i]++;
lst[i]++;
}
}
}
while(q--){
int x,k;
x=read(),k=read();
if(dy[k]<x){
puts("-1");
continue;
}
if(lst[k]>x){
if(tmplst[k]>x){
printf("%d\n",tmp[k]+sum[k]);
continue;
}
else{
int miu=x-tmplst[k];
int add=(miu/2)+(miu&1);
printf("%d\n",tmp[k]+sum[k]-add);
continue;
}
}
int minu=x-lst[k];
printf("%d\n",sum[k]-minu);
}
}