良い部分文字列の数
あなたは、バイナリ文字列s(各文字が0または1の場合、文字列がバイナリであることをリコール)を与えられています。
F(t)は(おそらく先行ゼロを有する)は、バイナリ形式で記述された整数tの進表現とします。例えば、F(011)= 3、F(00101)= 5、F(00001)= 1、F(10)= 2、F(000)= 0及びf(000100)= 4。
R-L + 1 = F(SL ... SR)場合はサブストリングSL、SL + 1、...、SRは良好です。
例えば= 1011文字列sは、5つの良いサブストリングを持っている:S1 ... S1 = 1、S3 ... S3 = 1、S4 ... S4 = 1、S1 ... S2 = 10とs2 ... S4 = 011。
あなたの仕事は、文字列sの良い部分文字列の数を計算することです。
あなたは独立したクエリをt答えなければなりません。
入力
クエリの数 - 最初の行は1つの整数T(1≤t≤1000)を含みます。
唯一の0と1を数字からなる、各クエリの唯一のラインは、文字列s(≤2⋅105| | S1≤)が含まれています。
SI | |≤2⋅105それは、Σiは= 1トンことが保証されています。
出力
各クエリの印刷のための1つの整数 - 文字列sの良い部分文字列の数。
いくつかは理解して使用バイナリ。
まず第一に、どれだけ多くの問題、10(2)と1(1)に加えて数0を先頭に付加する0以外の接頭辞、他のニーズを持っていないことを知っています。
1は、上記1 0のそれぞれの数及び位置を記録し、その後、列挙(既に以上20 ^ 2 | S |はるかに大きい)1つの20バック、各位置の数からなるとは、必要なプレフィックスを算出0そしてその後、プレフィックス0サイズライン上の1つの位置と、
コード:
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=200100;
const int M=200100;
const ll mod=1e9+7;
struct Node{
int post,date;
}a[N];
int solve(string p){
int b=0;
int ans=0;
for(int i=p.length()-1;i>=0;i--){
ans+=(p[i]-'0')*(1<<b);
b++;
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
ll ans=0;
string s;
cin>>s;
int len=0,k=0;
for(int i=0;i<s.length();i++){
if(s[i]=='0') len++;
else if(s[i]=='1'&&len){
a[++k].date=len;
a[k].post=i;
len=0;
}
}
for(int i=0;i<s.length();i++){
if(s[i]=='1') ans++;
if(i!=s.length()-1&&s[i]=='1'&&s[i+1]=='0') ans++;
}
// cout<<ans<<endl;
for(int i=1;i<=k;i++){
int l=a[i].post;
string b="";
for(int j=0;j<20;j++){
if(l+j>=s.length()) break;
b+=s[l+j];
int c=solve(b)-j-1;
// cout<<b<<" "<<c<<endl;
if(c<=a[i].date&&c) ans++;
}
}
cout<<ans<<endl;
}
return 0;
}