题面
题解思路
首先讲公式化简为
sum[r] - 100r > sum[l] - 100l
sum为前缀和。
这一步是很容易想到的,这样就只有一个变量了。
然后就是怎么通过枚举一个i来确定前面的数小于自己且最远的数是什么。
想了很久没想出来,y总这里使用了单调栈上二分来处理,之前没有见到过这种操作。
先使用一个降序的单调栈来保证单调栈上的每个数都是最远的(手模理解)。
如果这个数比栈顶还小,那肯定取不到答案,我们将它入栈。(如果一个数能取到答案,我们肯定不入队,因为在它前面肯定有更小的数)
如果比栈顶大,说明存在答案。
我们直接对单调栈上二分。
单调栈的题还是写太少了。
AC代码
/*从你的全世界路过.*/
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1000100;
int a[N] ;
long long sum[N] ;
int stk[N] ;
int n ;
void solve()
{
cin >> n ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
for (int i = 1 ; i <= n ; i++ )
{
sum[i] = sum[i-1] + a[i] - 100 ;
}
int top = 0 , res = 0 ;
stk[++top] = 0 ;
for (int i = 1 ; i <= n ; i++ )
{
if ( sum[stk[top]] > sum[i] )
stk[++top] = i ;
else if ( sum[stk[top]] < sum[i] )
{
int t1 = 1 , t2 = top ;
while ( t1 < t2 )
{
int mid = t1 + t2 >> 1 ;
if ( sum[stk[mid]] < sum[i] )
t2 = mid ;
else
t1 = mid + 1 ;
}
res = max(res,i-stk[t2]) ;
}
}
cout << res << "\n" ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve() ;
return 0 ;
}