C. Berry Jam(差值前缀,思维)
\(考虑枚举左半区间的点l\)
\(试图在右半区间找一个最小的点r\)
\(使得吃掉[l+1,r-1]的奶酪后两种奶酪数量相等\)
\(\color{Red}{于是我们可以预处理右半区间中两种奶酪的差值位置}\)
\(比如r[2]=6,表示在区间[6,2*n]中1奶酪比2奶酪多2个\)
\(r[-1]=9,表示在区间[9,2*n]中1奶酪比2奶酪少1个\)
\(因为存在负数,那么我们把下标都加100000:r[-1+100000]=9\)
\(那么我们开始枚举左半区间的点,比如枚举到2时\)
\(1奶酪比2奶酪多1,那我们就去看看r[-1+100000]的位置\)
\(因为这样可以刚好抵消,两种奶酪相等\)
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+9;
int r[maxn],a[maxn],t,n;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=100000-n;i<=100000+n;i++) r[i]=0;
for(int i=1;i<=2*n;i++) scanf("%d",&a[i]);
int q=0,w=0,ans=2*n;
for(int i=2*n;i>=n+1;i--)
{
a[i]==1?q++:w++;
r[q-w+100000]=i;//i右边
}
q=w=0;
if(!r[100000]) r[100000]=2*n+1;//右边一个都不选,差值为0
if(r[100000]) ans=min(ans,r[100000]-1);//左边一个都不选
for(int i=1;i<=n;i++)
{
a[i]==1?q++:w++;
if(r[w-q+100000]) ans=min(ans,r[w-q+100000]-i-1);
}
cout<<ans<<endl;
}
}