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;
}
posted @ 2025-03-05 15:53  sad_lin  阅读(32)  评论(0)    收藏  举报