[单调队列] hdu 3415 Max Sum of Max-K-sub-sequence
题意:
给n和k,再给你n个形成环的数
问你连续不超过k个数的最大和是多少
并输出区间,和一样以左端点最小。再一样以长度最小
思路:
我们记录前缀和sum[i]
开一个单调队列维护sum[i-1]的值最小
由于对于到当前位置的和为sum[i]-sum[j] 假设sum[j]越小,那么sum[i]就越大
所以里面维护的就是到当前位置符合要求最小的sun[j]
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #include"map" using namespace std; #define N 222222 int sum[N],v[N]; int q[2*N]; int main() { int t; cin>>t; while(t--) { int n,k; scanf("%d%d",&n,&k); //deque<int>q; sum[0]=0; for(int i=1;i<=n;i++) { scanf("%d",&v[i]); sum[i]=sum[i-1]+v[i]; } for(int i=n+1;i<2*n;i++) sum[i]=sum[i-1]+v[i-n]; int ans=-999999999,x,y; int top=0,ed=0; for(int i=1;i<2*n;i++) { while(top<ed && sum[q[ed-1]]>=sum[i-1]) ed--; q[ed++]=i-1; while(top<ed && i-q[top]>k) top++; int tep=sum[i]-sum[q[top]]; if(tep>ans) { ans=tep; x=q[top]+1; y=i; } } if(y>n) y-=n; printf("%d %d %d\n",ans,x,y); } return 0; }