【题解】 NKOJ P3545 【接近】——单调队列

#include<stdio.h>
#include<bits/stdc++.h>
#define H 100005
using namespace std;
struct node{int v,id;}Sum[H];
int N,T,P;
bool cmp(node a,node b){
	if(a.v==b.v)return a.id<b.id;
	return a.v>b.v;
}
void Work(){
	int L,R,ans,Cha;
	L=R=Cha=1234567890; 
	deque<int>Q;
	for(int i=0;i<=N;i++){
		//
		while(!Q.empty()&&Sum[Q.front()].v-Sum[i].v>=P){
			int k=Q.front();
			int A=min(Sum[k].id,Sum[i].id);
			int B=max(Sum[k].id,Sum[i].id);
			int C=Sum[k].v-Sum[i].v;
			if(C-P<=Cha){
				if(C-P==Cha){
					if(A==L)R=min(R,B);
					else if(A<L)L=A,R=B;
				}
				else ans=C,L=A,R=B;
				
				Cha=C-P;
			}
			Q.pop_front();
		}//讨论差大于等于P的情况
		Q.push_back(i);
		if(Q.size()!=1){
			int k=Q.front();
			int A=min(Sum[k].id,Sum[i].id);
			int B=max(Sum[k].id,Sum[i].id);
			int C=Sum[k].v-Sum[i].v;
			if(P-C<=Cha){
				if(P-C==Cha){
					if(A==L)R=min(R,B);
					else if(A<L)L=A,R=B;
				}
				else ans=C,L=A,R=B;
				Cha=P-C;
			}
		}//讨论差值小于等于P的情况 
	}
	printf("%d %d %d\n",ans,L+1,R);
}
int main(){
	scanf("%d%d",&N,&T);
	for(int i=1;i<=N;i++){
		int x;scanf("%d",&x);
		Sum[i].v=Sum[i-1].v+x;
		Sum[i].id=i;
	}
	sort(Sum,Sum+1+N,cmp);//数组一定要从[0,N]排序,因为会有从[1,i]的连续区间的情况 
	while(T--){
		scanf("%d",&P);
		Work();
	}
}
  

  

猜你喜欢

转载自www.cnblogs.com/go-bananas/p/11348231.html