题意 :
- 给定长度为n的序列和数字s,找出最长的区间 [ l , r ] [l,r] [l,r],使得 ∀ i ∈ [ l , r ] , p r e i − p r e l − 1 + s ≥ 0 \forall i \in [l,r], pre_i-pre_{l-1}+s \geq0 ∀i∈[l,r],prei−prel−1+s≥0,其中 p r e i pre_i prei表示前缀和
思路 :
- 考虑双指针,对某一段 [ l , r ] [l,r] [l,r]区间满足答案要求,则更新答案,且右指针移动
- 若右指针移动后不满足条件,则不断移动左指针直到满足条件
- 注意如何设置初始值,来应对无解的情况
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_set>
#include <math.h>
using namespace std;
typedef long long ll;
//typedef pair<int, int> PII;
#define endl '\n'
#define fi first
#define se second
#define push_back
#define rep(i, l, r) for (ll i = l; i <= r; i ++ )
#define int long long
const int N = 2e5 + 10;
int a[N];
void solve()
{
int n, s; cin >> n >> s;
for (int i = 1; i <= n && cin >> a[i]; i ++ ) a[i] += a[i - 1];
int l = 1, r = 0;
for (int j = 1, i = 1; j <= n; j ++ )
{
while (i <= j && a[j] - a[i - 1] + s < 0) i ++ ;
if (r - l + 1 < j - i + 1)
l = i, r = j;
}
if (r == 0) cout << -1 << endl;
else cout << l << ' ' << r << endl;
}
signed main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
int _;
cin >> _;
while (_ -- )
solve();
// return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_set>
#include <math.h>
using namespace std;
//typedef long long ll;
typedef pair<int, int> PII;
#define endl '\n'
#define fi first
#define se second
#define push_back
#define rep(i, l, r) for (ll i = l; i <= r; i ++ )
#define int long long
const int N = 2e5 + 10;
int n, s;
int a[N];
int l, r, ansl, ansr, sum;
void init()
{
l = r = 1, sum = 0, ansl = ansr = -1;
}
void update()
{
if (r - l > ansr - ansl) ansl = l, ansr = r;
}
void solve()
{
cin >> n >> s;
for (int i = 1; i <= n && cin >> a[i]; i ++ );
init();
while (l <= n && r <= n + 1)
{
if (sum + s >= 0) update(), sum += a[r ++ ];
else sum -= a[l ++ ];
}
if (ansr == -1) cout << -1 << endl;
else cout << ansl << ' ' << ansr - 1 << endl;
}
signed main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
int _;
cin >> _;
while (_ -- )
solve();
// return 0;
}