题目大意:给出循环队列,求区间长度不大于K的区间最大和,并输出下标
解题思路:记录前缀和,单调队列(升序),max(sum[i] - sum[q[head]], Max); (记录下标位置有点坑)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define N 2000010
using namespace std;
int n, k;
int a[N], q[N];
int head, rear;
void enqueue(int i)
{
while (head <= rear && a[i] < a[ q[rear] ])
{
rear--;
}
q[++rear] = i;
}
void dequeue(int i)
{
if (i - q[head] > k)
{
head++;
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &k);
head = 0, rear = -1;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
a[i + n] = a[i];
}
a[0] = 0;
for (int i = 1; i <= n + k; i++)
{
a[i] += a[i - 1];
}
int Max = -0x3f3f3f3f;
int px, py;
enqueue(0);
for (int i = 1; i <= n + k ; i++)
{
dequeue(i);
if (a[i] - a[ q[head] ] > Max)
{
Max = a[i] - a[ q[head] ];
// cout << i << ' ' << a[i] << ' ' << q[head] << ' ' << a[q[head]] << ' ' << Max << endl;
px = q[head] + 1;
py = i;
}
enqueue(i);
}
printf("%d %d %d\n", Max, px, py > n ? py - n : py);
}
}
/*
6 3
6 -1 2 -6 5 -5
6 4
6 -1 2 -6 5 -5
6 3
-1 2 -6 5 -5 6
6 6
-1 -1 -1 -1 -1 -1
8 8
0 1 2 3 1 0 0 0
*/