众所周知实验室的dousha(也就是dyx)学姐不仅打码强,篮球也打的猛(身体是革命的本钱啊)。
某一天doush学姐又带着实验室里的大三学长们去打球了,dousha学姐连续投了n个球,被学长们用一个长度为n的01字符串s(只包含0或者1的字符串)记录了下来。
s[i]=1代表dousha学姐的第i个投球进了,s[i]=0代表dousha学姐的第i个投球没进。
现在dousha学姐想知道她在这n次投篮的过程中,有多少个连续进球的时期,直观得说就是这个01字符串中有几个连续的由1组成的区间(111算1个区间而不是6个)。
但是由于记录数据的机器坏掉了,它会在每一秒变化这个01字符串的某一个位置上的数。原本是0就会变成1,原本是1就会变成0。
这就能难倒万能的dousha学姐么,她非常迅速得计算出了初始以及q次改变中每次改变后的01字符串中,连续的由1组成的区间个数,机智的小可爱们能做到么?
输入描述:
第一行包含两个正数n和q,分别代表字符串s的长度以及改变操作的次数。(1≤n,q≤1×106)第二行包含一个长度为n的字符串s,代表初始记录下来的01字符串。第三行包含q个整数ai,代表第i次操作分别改变了第几次操作的进球状况。(1≤ai≤n)
输出描述:
输出q+1行,每行一个整数,分别代表初始字符串以及q次改变操作每次操作后的字符串s中,连续的由1组成的区间个数。
思路:
直接判断改变位置左右可能的所有的情况,当时脑子比较浆糊,其实有些情况可以合并的
#include<stdio.h>
#include<iostream>
#include<vector>
#include<math.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char s[1000005];
int main(){
int n,q;
scanf("%d%d",&n,&q);
getchar();
for(int i=1;i<=n;i++)
scanf("%c",&s[i]);
int num=0,flag=0;
for(int i=1;i<=n;i++){
if(s[i]=='1'&&flag==0){
flag=1;
num++;
}
else if(flag==1&&s[i]=='0'){
flag=0;
}
}
//算出开始的连续区间个数
cout<<num<<endl;
for(int i=1;i<=q;i++){
int oper;
scanf("%d",&oper);
if(n==1){//特判n=1的情况
if(s[1]=='0')s[1]='1',printf("1\n");
else s[1]='0',printf("0\n");
continue;
}
if(oper>1&&oper<n){//改变的点在中间
if(s[oper]=='1'){
if(s[oper+1]=='1'){//1 1 1
if(s[oper-1]=='1'){
num++;
}
}
else if(s[oper+1]=='0'){ //0 1 0
if(s[oper-1]=='0'){
num--;
}
}
s[oper]='0';
}
else if(s[oper]=='0'){
if(s[oper+1]=='1'){//1 0 1
if(s[oper-1]=='1'){
num--;
}
}
else if(s[oper+1]=='0'){// 0 0 0
if(s[oper-1]=='0'){
num++;
}
}
s[oper]='1';
}
}
else if(oper==1){//在开头
if(s[oper]=='0'){
if(s[oper+1]=='0')num++;//0 0
s[oper]='1';
}
else{
if(s[oper+1]=='0')num--;// 1 0
s[oper]='0';
}
}
else if(oper==n){//在末尾
if(s[oper]=='0'){
if(s[oper-1]=='0')num++;//0 0
s[oper]='1';
}
else{
if(s[oper-1]=='0')num--;//0 1
s[oper]='0';
}
}
//for(int i=1;i<=n;i++)cout<<s[i];
// cout<<endl;
printf("%d\n",num);
}
}