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.csdn.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;
}

优质内容筛选与推荐>>
1、vector作为函数返回值
2、GitHub使用
3、Xcode 与 iOS SDK 版本 演变史
4、在Mac OS X下架设和使用Xcode的SVN版本管理环境
5、UITableView 删除表格单元写法


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号