题目链接
CF1738E Balance Addicts
解题思路
发现我们可以直接枚举左端点 \(L\),那么此时显然右端点 \(R\) 的取值范围也随之确定,那么此时 \(L\) 能往右移当且仅当 \(L + 1<R\) 与 \(a_{L+1} = 0\),\(R\) 能往左移当且仅当 \(L<R - 1\) 与 \(a_{R-1} = 0\)。
那么 \(L,R\) 的取值范围确定后,此时会有以下两种情况:
-
\(L,R\) 的取值范围不相交,此时显然枚举分的段数 \(k\) 然后两端组合数部分相乘即可。
-
\(L,R\) 的取值部分相交,此时直接让两个取值范围一定,然后枚举分的段数 \(k\),此时显然 \(k\) 为偶数,依然组合数计算即可。
由于双指针,时间复杂度 \(O(n)\)。
参考代码
ll n;
ll a[1000010];
ll L,R;
ll pre[1000010],suf[1000010];
ll ans;
ll l,r;
void solve()
{ans=1;cin>>n;forl(i,1,n)cin>>a[i];forl(i,1,n)pre[i]=pre[i-1]+a[i];suf[n+1]=0;forr(i,n,1)suf[i]=suf[i+1]+a[i];R=n;forL(L,1,n,L<R){while(L<R-1 && suf[R]<pre[L])R--;if(pre[L]==suf[R]){l=L,r=R;while(L<R-1 && suf[R-1]==pre[L])R--;while(L+1<R && suf[R]==pre[L+1])L++;ll S=0;if(L==R-1 && pre[L]==suf[L+1]){forll(k,0,r-l+1,2)S=(S+C(r-l+1,k))%mod;ans=(ans*S)%mod;continue;}forl(k,0,min(L-l+1,r-R+1))S=(S+C(L-l+1,k)*C(r-R+1,k)%mod)%mod;ans=(ans*S)%mod;}}cout<<ans<<endl;
}