Bound Found(思维+尺取)

时间:2023-03-09 19:41:05
Bound Found(思维+尺取)

Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two parts: a sequence of n integer values and a non-negative integer t. We'll not go into details, but researchers found out that a signal encodes two integer values. These can be found as the lower and upper bound of a subrange of the sequence whose absolute value of its sum is closest to t. 

You are given the sequence of n integers and the non-negative target t. You are to find a non-empty range of the sequence (i.e. a continuous subsequence) and output its lower index l and its upper index u. The absolute value of the sum of the values of the sequence from the l-th to the u-th element (inclusive) must be at least as close to t as the absolute value of the sum of any other non-empty range.

Input

The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.

Output

For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n.

Sample Input

5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0

Sample Output

5 4 4
5 2 8
9 1 1
15 1 15
15 1 15

思路:这个题拿到手,很容易想到的是暴力,但是很明显,必然会超时,所以,我们要换种思路,既然是尺取题,尺取关键要单调,这是个比较难处理的过程,没想好如何去尺取处理,然后参考了一篇博客,恍然大悟,博客链接:https://blog.****.net/acm_cxq/article/details/51854210,很巧妙的做法,只是没想到,关键就是求和排序,这是个突破点

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>
#define INF 0x3f3f3f3f const int maxn=1e5+5;
typedef long long ll;
using namespace std;
ll a[maxn];
ll abss(ll x) {
if(x<0) {
return -x;
} else {
return x;
}
}
struct node {
ll sum,id;
} p[maxn]; bool cmp(node x,node y) {
return x.sum<y.sum;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n,k;
while(cin>>n>>k) {
if(n==0&&k==0) {
break;
}
p[0].sum=0,p[0].id=0;
for(int t=1; t<=n; t++) {
cin>>a[t];
p[t].sum=p[t-1].sum+a[t];
p[t].id=t; }
sort(p,p+n+1,cmp);
int s;
for(int t=0; t<k; t++) {
scanf("%d",&s);
ll l=0,r=1;
ll ans=INF;
ll ansl,ansr,anss;
while(r<=n&&l<=n) {
ll ss=abss(p[r].sum-p[l].sum); if(ans>abss(ss-s)) {
anss=ss;
ans=abss(ss-s);
ansl=p[l].id;
ansr=p[r].id;
}
if(ss>s) {
l++;
} else if(ss<s) {
r++;
} else break;
if(l==r) {
r++;
}
}
if(ansl>ansr)swap(ansl,ansr);
cout<<anss<<" "<<ansl+1<<" "<<ansr<<endl;
}
}
return 0;
}