题解
由于看的是区间平均值是否大于0,我们可以转换为区间和是否大于0,这样的话就可以先用前缀和预处理前缀和同时用记录一下这个前缀和的右端点,然后用升序排序,升序排序过后就一定能满足后续区间减去前面任意一个区间,区间和都大于0这个要求,现在的需要判断的就是右端点谁比较大,我们取右端点最小的前缀和,作为可能的答案,然后顺序遍历求出最大值即可。比方说升序排序后第3个区间,那么能作为答案的一定是前两个区间,因为后面的区间平均值一定小于0,那我们只要判断第3个区间和前两个区间右端点是否满足第3个区间在前两个之后,如果能满足即为一个答案。为了让答案最优,我们可以选择右端点最小的那个数作为更新。
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct n
{
int num, soc;
}x[100005];
bool cmp(struct n a, struct n b)
{
if (a.soc != b.soc)return a.soc < b.soc;
else return a.num < b.num;
}
int main()
{
int t;
cin >> t;
while (t--)
{
x[0].soc = x[0].num = 0;
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> x[i].soc;
x[i].soc += x[i - 1].soc;
x[i].num = i;
}
sort(x , x + n + 1, cmp);
int k = n, ans = 0;
for (int i = 1; i <= n; i++)
{
k = min(k, x[i].num);
ans = max(ans, x[i].num - k);
}
cout << ans << endl;
}
return 0;
}