因为要绝对值接近t,我们可以看成s[i]-s[j]接近t,所以把前缀和排序,然后用头尾指针动态处理即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
struct pi{
LL s;
int id;
}pp[100005];
int cmp(pi a ,pi b){
return a.s<b.s;
}
int get(LL s,int n){
int le,ri,mid;
le=1;
ri=n;
while(le<=ri){
mid=(le+ri)/2;
if(pp[mid].s<s) le=mid+1;
else ri=mid-1;
}
return le;
}
LL aabs(LL a){
if(a<0) a=-a;
return a;
}
int main()
{
int i,j,n,k,p,f,x1,x2,tear,rear;
LL m;
while(1){
scanf("%d%d",&n,&k);
if(n==0&&k==0) break;
pp[0].s=0;
pp[0].id=0;
for(i=1;i<=n;i++){
scanf("%d",&p);
pp[i].s=pp[i-1].s+p;
pp[i].id=i;
}
sort(pp+1,pp+1+n,cmp);
for(i=0;i<k;i++){
scanf("%d",&f);
m=(LL)1<<60;
x1=1;
x2=1;
for(j=1;j<=n;j++){
if(aabs(aabs(pp[j].s)-f)<aabs(aabs(m)-f)){
m=pp[j].s;
x1=1;
x2=pp[j].id;
}
}
tear=1;
rear=2;
while(rear<=n){
if(rear>tear&&aabs(aabs(pp[rear].s-pp[tear].s)-f)<aabs(aabs(m)-f)){
m=pp[rear].s-pp[tear].s;
x1=min(pp[tear].id,pp[rear].id)+1;
x2=max(pp[tear].id,pp[rear].id);
}
while(rear==tear||rear<=n&&pp[rear].s-pp[tear].s<f){
if(rear>tear&&aabs(aabs(pp[rear].s-pp[tear].s)-f)<aabs(aabs(m)-f)){
m=pp[rear].s-pp[tear].s;
x1=min(pp[tear].id,pp[rear].id)+1;
x2=max(pp[tear].id,pp[rear].id);
}
rear++;
}
if(rear<=n){
if(aabs(aabs(pp[rear].s-pp[tear].s)-f)<aabs(aabs(m)-f)){
m=pp[rear].s-pp[tear].s;
x1=min(pp[tear].id,pp[rear].id)+1;
x2=max(pp[tear].id,pp[rear].id);
}
}
else break;
while(tear<rear&&pp[rear].s-pp[tear].s>=f){
if(aabs(aabs(pp[rear].s-pp[tear].s)-f)<aabs(aabs(m)-f)){
m=pp[rear].s-pp[tear].s;
x1=min(pp[tear].id,pp[rear].id)+1;
x2=max(pp[tear].id,pp[rear].id);
}
tear++;
}
if(tear<rear){
if(aabs(aabs(pp[rear].s-pp[tear].s)-f)<aabs(aabs(m)-f)){
m=pp[rear].s-pp[tear].s;
x1=min(pp[tear].id,pp[rear].id)+1;
x2=max(pp[tear].id,pp[rear].id);
}
}
}
cout<<aabs(m);
printf(" %d %d\n",x1,x2);
}
}
}