折半搜索求调
查看原帖
折半搜索求调
577987
caizhetong楼主2023/8/5 20:43
#include <bits/stdc++.h>
using namespace std;
long long n,num,ans,r;
long long tota,totb,numa,numb,cnta,cntb;
long long z[2000010],w1[2000010],w2[2000010];
struct tx{
	long long a,b;
}a[2000010],b[2000010];
void dfs(long long x)
{
	if(x>n/2) return;
	numa+=1<<(x-1);
	//cout<<w1[numb]<<" "<<w2[numa]<<"\n";
	if(w1[numb]==0||w2[numa]==0)
	{
		w1[numa]=1;
		w2[numb]=1;
		tota+=z[x];
		cnta++;
		a[cnta].a=tota;
		a[cnta].b=totb;
		if(a[cnta].a<a[cnta].b) swap(a[cnta].a,a[cnta].b);
		dfs(x+1);
		tota-=z[x];
	}
	numa-=1<<(x-1);
	
	//cout<<w1[numb]<<" "<<w2[numa]<<"\n";
	numb+=1<<(x-1);
	if(w1[numb]==0||w2[numa]==0)
	{
		w1[numa]=1;
		w2[numb]=1;
		totb+=z[x];
		cnta++;
		a[cnta].a=tota;
		a[cnta].b=totb;
		if(a[cnta].a<a[cnta].b) swap(a[cnta].a,a[cnta].b);
		dfs(x+1);
		totb-=z[x];
	}
	numb-=1<<(x-1);
	
	dfs(x+1);
}
void dfs1(long long x)
{
	//cout<<x;
	//cout<<numb<<"\n";
	if(x>n) return;
	
	numa+=1<<(x-1);
	if(w1[numb]==0||w2[numa]==0)
	{
		w1[numa]=1;
		w2[numb]=1;
		tota+=z[x];
		cntb++;
		b[cntb].a=tota;
		b[cntb].b=totb;
		//cout<<b[cntb].a<<" "<<b[cntb].b<<" "<<b[cntb].a-b[cntb].b<<"\n";
		if(b[cntb].a>b[cntb].b) swap(b[cntb].a,b[cntb].b);
		//cout<<b[cntb].a<<" "<<b[cntb].b<<" "<<b[cntb].a-b[cntb].b<<"\n";
		dfs1(x+1);
		tota-=z[x];
	}
	numa-=1<<(x-1);
	
	numb+=1<<(x-1);
	if(w1[numb]==0||w2[numa]==0)
	{
		w1[numa]=1;
		w2[numb]=1;
		totb+=z[x];
		cntb++;
		b[cntb].a=tota;
		b[cntb].b=totb;
		//cout<<b[cntb].a<<" "<<b[cntb].b<<" "<<b[cntb].a-b[cntb].b<<"\n";
		if(b[cntb].a>b[cntb].b) swap(b[cntb].a,b[cntb].b);
		//cout<<b[cntb].a<<" "<<b[cntb].b<<" "<<b[cntb].a-b[cntb].b<<"\n";
		dfs1(x+1);
		totb-=z[x];
	}
	numb-=1<<(x-1);
	
	dfs1(x+1);
}
bool px(tx a,tx b)
{
	if(a.a-a.b<b.a-b.b) return true;
	if(a.a-a.b<b.a-b.b) return false;
	else return false;
}
int main(){
   //freopen("ti.in","r",stdin);

	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>z[i];
	}
	dfs(1);
	dfs1(n/2+1);
	sort(a+1,a+1+cnta,px);
	sort(b+1,b+1+cntb,px);
	
	r=cntb;
	for(int i=1;i<=cnta;i++)
	{
		if(a[i].a-a[i].b==a[i-1].a-a[i-1].b)
		{
			ans+=num;
			continue;
		}
		num=0;
		while(a[i].a-a[i].b+b[r].a-b[r].b>=0&&r>1)
		{
			//cout<<a[i].a-a[i].b<<" "<<b[r].a-b[r].b<<"\n";
			if(a[i].a-a[i].b+b[r].a-b[r].b==0) num++;
			r--;
		}
		ans+=num;
	}
	for(int i=1;i<=cnta;i++)
	{
		if(a[i].a-a[i].b==0) ans++;
		else break;
	}
	for(int i=cntb;i>=1;i--)
	{
		if(b[i].a-b[i].b==0) ans++;
		else break;
	}
	cout<<ans<<"\n";
	//cout<<cnta<<" "<<cntb;
	
	/*
	for(int i=1;i<=cnta;i++)
	{
		//cout<<a[i].a<<" "<<a[i].b<<" "<<a[i].a-a[i].b<<"\n"; 
	}
	//cout<<"\n";
	for(int i=1;i<=cntb;i++)
	{
		//cout<<b[i].a<<" "<<b[i].b<<" "<<b[i].a-b[i].b<<"\n"; 
	}
	*/
	
    //fclose(stdin);
	return 0;
}

2023/8/5 20:43
加载中...