E. Game with Binary String
https://codeforces.com/contest/2070/problem/E
每一回合 A 消耗 \(2\) 个 \(0\),B 最优一定会消耗 \(1\) 个 \(0\) 和 \(1\) 个 \(1\),所以每回合会消耗 \(3\) 个 \(0\) 和 \(1\) 个 \(1\)。
设当前有 \(c_0\) 个 \(0\),\(c_1\) 个 \(0\),当 \(c_0-3c_1\ge2\),经过若干个回合B操作完后剩下了一堆0,A一定赢。
当 \(c_0-3c_1=1/0\) 时,剩下的 \(0\) 不够 A 操作,A 一定输。
当 \(c_0-3c_1=-1\) 时,没有0给B操作,A一定赢。
当 \(c_0-3c_1\le-2\) 时,A没有 \(0\) 能操作,A 一定输。
设长度为 \(l\),\(c_0-3c_1=c_0-3(l-c_0)=4c_0-3l\),此时只要从前缀查找即可。
#include<bits/stdc++.h>
#define ll long long
#define int ll
#define ls t[p].l
#define rs t[p].r
#define re register
#define pb push_back
#define pir pair<int,int>
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lowbit(x) x&-x;
using namespace std;
const int N=3e5+10;
const int M=1e6+4;
const int lim=N*3;
const int mod=998244353;
mt19937 rnd(251);
int n;
int b[N];
int t[N*20];
int ans=0;
map<int,int> mp;
void add(int x,int k){
while(x<=lim*5){
t[x]+=k;
x+=lowbit(x);
}
}
int query(int x){
int sum=0;
while(x){
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
void solve(){
cin>>n;
int cnt=0;
mp[lim]=1;
add(lim,1);
for(int i=1;i<=n;i++){
char c;
cin>>c;
if(c=='0'){
cnt++;
}
b[i]=cnt*4-i*3;
ans+=mp[b[i]+lim+1]+query(b[i]+lim-2);
mp[b[i]+lim]++;
add(b[i]+lim,1);
}
cout<<ans<<"\n";
}
signed main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(nullptr);
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}
#include<bits/stdc++.h>
#define ll long long
#define int ll
#define ls t[p].l
#define rs t[p].r
#define re register
#define pb push_back
#define pir pair<int,int>
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lowbit(x) x&-x;
using namespace std;
const int N=3e5+10;
const int M=1e6+4;
const int lim=1e7;
const int mod=998244353;
mt19937 rnd(251);
int root;
int n;
int a[N];
int b[N];
int tot;
struct ss{
int l,r,w;
}t[N*20];
void change(int &p,int l,int r,int x,int w){
if(!p) p=++tot;
if(l==r){
t[p].w+=w;
return;
}
int mid=(l+r)>>1;
if(x<=mid){
change(ls,l,mid,x,w);
}
else{
change(rs,mid+1,r,x,w);
}
t[p].w=t[ls].w+t[rs].w;
}
int query(int p,int l,int r,int x,int y){
if(!p||l>y||r<x) return 0;
if(x<=l&&r<=y){
return t[p].w;
}
int mid=(l+r)>>1;
return query(ls,l,mid,x,y)+query(rs,mid+1,r,x,y);
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
char c;
cin>>c;
a[i]=c-'0';
}
int cnt=0;
for(int i=1;i<=n;i++){
if(a[i]==0){
cnt++;
}
b[i]=cnt*4-i*3;
}
change(root,-lim,lim,b[0],1);
int ans=0;
for(int i=1;i<=n;i++){
ans+=query(root,-lim,lim,-lim,b[i]-2)+query(root,-lim,lim,b[i]+1,b[i]+1);
change(root,-lim,lim,b[i],1);
}
cout<<ans<<"\n";
}
signed main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(nullptr);
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}

浙公网安备 33010602011771号