题目
思路
对于每个数,后面一个数是否是最小的前缀和与该数有较大关系,如a,b,c,
决定c是否是最小前缀和与a无关,与b有关,将a扩展到若干个数的和,那么b+c若大于0则必定不成立,因此我们边知道,从m位往前推,大于0的时候就要考虑变号,至于变谁的号,那必然是最大的元素的号,同样,m之后小于0就变最小的元素的号,这里我们用priority_queue实现操作
AC代码
#include <bits/stdc++.h>
using namespace std;
int arr[200005]={0};
int main()
{
int t;scanf("%d",&t);
for(int tt=0;tt<t;tt++)
{
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",arr+i);
long long s=0,counts=0;
priority_queue<int> a;
priority_queue<int,vector<int>,greater<int> > b;
for(int i=m;i>1;i--)
{
s+=arr[i];
if(arr[i]>0) a.push(arr[i]);
if(s>0)
{
counts++;
s-=2ll*a.top();
a.pop();
}
}
s=0;
for(int i=m+1;i<=n;i++)
{
if(arr[i]<0) b.push(arr[i]);
s+=arr[i];
if(s<0)
{
counts++;
s-=2ll*b.top();
b.pop();
}
}
printf("%lld\n",counts);
}
return 0;
}