题目大意:
一个长度为n的序列,你需要要从中找到一个上界r和下界l让[l,r]之间的和的绝对值与t最相近
分析:
尺取法。其实第一感觉就是尺取法,但是如果直接用原序列,原序列不具有单调性,没办法使用尺取法,而这题巧
妙的地方就在于需要用到前缀和。用pair<int,int>sum[]的first存前i个数的和second存i也就是上界
(sum[0]={0,0}),然后将sum排序,再用尺取法就行了,注意[l,r]的区间和,实际上是a[r]-a[l-1],所以
ansl+1.(本题坑点:初始的ans值一定要设的比较大0x3f3f3f3f是不够的)
code:
#define debug
#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<functional>
#include<iomanip>
#include<map>
#include<set>
#define pb push_back
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
#define lson l,m,rt<<1
#define cmm(x) cout<<"("<<(x)<<")";
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int maxn=1e5;
const int INF=0x3f3f3f3f;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int MOD=10007;
//----
//define
PII sum[maxn+10];
int n,k,t;
//solve
void solve() {
while(cin>>n>>k&&n&&k){
sum[0]=make_pair(0,0);
int tot=0;
for(int i=1;i<=n;i++){
int tmp;
cin>>tmp;
tot+=tmp;
sum[i]=make_pair(tot,i);
}
sort(sum,sum+n+1);
for(int i=0;i<k;i++){
cin>>t;
int l=0,r=1,ans=inf,ansl=0,ansr=0;
while(r<=n){
int tmp=sum[r].first-sum[l].first;
if(abs(tmp-t)<=abs(ans-t)){
ans=tmp;
ansl=sum[l].second;
ansr=sum[r].second;
}
if(tmp>t)l++;
else if(tmp<t)r++;
else break;
if(l==r)r++;
}
if(ansl>ansr)swap(ansl,ansr);
cout<<ans<<" "<<ansl+1<<" "<<ansr<<endl;
}
}
}
int main() {
ios_base::sync_with_stdio(0);
#ifdef debug
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
cin.tie(0);
cout.tie(0);
solve();
return 0;
}