题意:输出最长01数目相等的子序列和子串的长度
题解:子序列直接就是较小的那个*2,子串的话二分一下长度,每次用前缀和判一下有没有就可以了
主要是没写过关于偶数单调的二分,记录一下
#include <bits/stdc++.h>
using namespace std;
#define maxn int(5e5+5)
const double eps = 1e-6;
const double INF = 1e9;
const double pi = acos (-1.0);
typedef long long int ll;
int sum[maxn];
int n;
int check(int mid){
for(int i=1;i+mid-1<=n;i++){
if(sum[i+mid-1]-sum[i-1]==mid/2)return 1;
}
return 0;
}
char s[maxn];
int main(){
#ifndef ONLINE_JUDGE //if not define 如果没有定义这个的话就执行下面
//freopen("input.in", "r", stdin); //只改变输入流的文件指针,读入这个文件的内容(必须要有input这个文件)stdin是标准输入流的文件指针
//freopen("input.in", "w", stdout); //只改变输出流的文件指针,写入output内(如果没有output这个文件就会自动生成)stdout是标准输出流的文件指针
#endif
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++){
if(s[i]=='1')sum[i]=sum[i-1]+1;
else sum[i]=sum[i-1];
}
int l=0,r=INF,ans;
while(l<=r){
int mid=(l+r)/2;
if(mid%2==1)mid++;
//cout<<mid<<endl;
if(check(mid)){
ans=mid;
l=mid+2;
}else r=mid-2;
}
cout<<ans<<" "<<min(sum[n],n-sum[n])*2<<endl;
}