计数问题。
考虑纯暴力写法:
string s; cin>>s;
int n=s.size(); s=' '+s;
int ans=0;
for(int l=1;l<=n;l++)
for(int r=l;r<=n;r++)
for(int i=l;i<=r;i++)
for(int j=i;j<=r;j++)
if(count(begin(s)+i,begin(s)+j+1,'1')==count(begin(s)+i,begin(s)+j+1,'0'))
ans++;
cout<<ans<<endl;
O(n^5)的复杂度,复杂上天。
考虑L=1,R=n时,满足条件的(x,y)对数的优化写法:
vector<int>pre(n+10);
for(int i=1;i<=n;i++)
pre[i]=(pre[i-1]+(s[i]=='1'?1:-1));
map<int,int>cnt;
int ans=0;
for(int i=1;i<=n;i++){
ans+=cnt[pre[i]];
cnt[pre[i]]++;
}
复杂度O(nlogn)。
再根据乘法原理 ,可以进一步处理所有[L,R]下(x,y)的对数。
#include<bits/stdc++.h>
using namespace std;
void __p(int x) {cerr<<x;}
void __p(long long x){cerr<<x;}
void __p(long double x){cerr<<x;}
void __p(double x){cerr<<x;}
void __p(string s){cerr<<s;}
void __p(char s){cerr<<s;}
void _print(){cerr<<"]\n";}
template<typename T,typename... V>//定义类模版
void _print(T t,V... v){__p(t);if(sizeof...(v))cerr<<",";_print(v...);}
#define debug(x...) cerr<<"["<<#x<<"] = ["; _print(x);
#define see1 cout<<"-------------\n";
#define see2 cerr<<"-------------\n";
#define io ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long
#define double long double
#define sqrt sqrtl
/*
1.进行移位运算时, 1ll<<n ,1后面不要忘了ll否则会溢出
2.数组开太大放到外面,作为全局数组
3.dfs递归深度超过几千层可能会溢出
4.accumulate(begin(a),end(a),0LL);
*/
const int p=1e9+7;
void solve()
{
string s; cin>>s;
int n=s.size();
s=' '+s;
vector<int>pre(n+10);
for(int i=1;i<=n;i++)
pre[i]=pre[i-1]+(s[i]=='1'?1:-1);
int ans=0;
map<int,int>cnt;
for(int i=0;i<=n;i++){
ans=(ans+cnt[pre[i]]*(n-i+1))%p;
cnt[pre[i]]=(cnt[pre[i]]+i+1)%p;
}
cout<<ans<<endl;
}
signed main()
{
io
int t=1;
cin>>t;
while(t--){
solve();
}
}
for(int i=1;i<=n;i++)
pre[i]=(pre[i-1]+(s[i]=='1'?1:-1));
int ans=0;
for(int i=0;i<=n;i++){
ans=(ans+cnt[pre[i]]*(n-i+1))%p;
cnt[pre[i]]=(cnt[pre[i]]+i+1)%p;
}
cout<<ans<<endl;
25/4/30