B
题意:
给一个01串,寻找这个串的最长0、1个数相等字串和0、1个数相等子序列
思路:
01子序列直接看0、1个数中最少的即可,找子序列二分答案长度,O(n)看每个长度是否合法即可
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],sum[maxn],ob[maxn];
int n;
int check(int len){
// cout<<len<<endl;
if(len>n)return 0;
int l=1,r=len;
while(r<=n){
if((sum[r]-sum[l-1])==(r-l+1)/2){
return 1;
}
l++;r++;
}
return 0;
}
int main(){
cin>>n;
int ansa,ansb;
int cnt=0,on=1;
char s[maxn];cin>>s+1;
for(int i=1;i<=n;i++){
a[i]=s[i]-'0';
if(a[i])cnt++;
sum[i]=sum[i-1]+a[i];
if(i%2==0){
ob[on++]=i;
}
}
// cout<<cnt<<endl;
ansb=min(cnt,n-cnt)*2;
// for(int i=1;i<on;i++){
// cout<<ob[i]<<endl;
// }
// cout<<endl;
// cout<<on<<endl;
int l=1,r=on;
while(l<=r){
int mid=l+r>>1;
// cout<<mid<<endl;
// cout<<l<<" "<<r<<endl;
if(check(ob[mid])){
// cout<<"asd"<<endl;
ansa=ob[mid];
l=mid+1;
}
else{
r=mid-1;
}
}
cout<<ansa<<" "<<ansb<<endl;
}