题目大意:有一个数字序列,可循环,求出长度不超过K的最大连续数字和
单调队列必杀之。。。另外看到discuess里面有用线段树做的,我想用线段树的话一定很蛋疼
贴上代码回味一下美味的单调队列
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<queue>
#include<vector>
using namespace std;
const int MAXN = 200020;
const int INF = 999999999;
struct node
{
int sq,val;
}p[MAXN];
int n,bound,k;
int a[MAXN];
int q[MAXN];
void solve()
{
bound=n*2;
p[0].sq=0;p[0].val=0;
for(int i=1;i<=bound;i++)
{
p[i].sq=i;
p[i].val=p[i-1].val+a[(i-1)%n+1];
}
int front,rear;
front=rear=0;
q[rear++]=0;
int temp,ans=-INF,ansl,ansr;
for(int i=1;i<=bound;i++)
{
temp=p[i].val-p[q[front]].val;
int tl=p[q[front]].sq,tr=p[i].sq;
if(temp>ans)
{
ans=temp;
ansl=tl;
ansr=tr;
}
else if(temp==ans)
{
if(tl==ansl)
{
if(ansr-ansl>tr-tl)
{
ansl=tl;
ansr=tr;
}
}
else if(tl<ansl)
{
ansl=tl;
ansr=tr;
}
}
while(front<rear&&p[q[front]].sq+k<=i)front++;
while(front<rear&&p[i].val<p[q[rear-1]].val)rear--;
q[rear++]=i;
}
printf("%d %d %d\n",ans,(ansl-1)%n+2,(ansr-1)%n+1);
}
int main()
{
//freopen("3415.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
solve();
}
return 0;
}