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
思路:维护前缀和,排序后维护双指针取值,细节直接看代码
using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; typedef pair<LL, LL> PLL; const int maxm = 1e5+5; int n, k; LL C[maxm]; void add(int x, int val) { for(; x <= n; x += lowbit(x)) C[x] += val; } LL getsum(int x) { LL ret = 0; for(; x; x -= lowbit(x)) ret += C[x]; return ret; } struct Node { LL val; int id; bool operator<(const Node &a) const { return val < a.val; } } Nodes[maxm]; int main() { ios::sync_with_stdio(false), cin.tie(0); int t, val; while(cin >> n >> k && n+k) { memset(C, 0, sizeof(C)); for(int i = 1; i <= n; ++i) { cin >> val; add(i, val); Nodes[i] = {getsum(i), i}; } Nodes[0].id = 0, Nodes[0].val = 0; sort(Nodes,Nodes+1+n); while(k--) { int l = 0, r = 1, ansL, ansR; LL ans, t, diff = 0x3f3f3f3f; cin >> t; while(l <= n && r <= n) { LL val = Nodes[r].val - Nodes[l].val; if(abs(val - t) < diff) { ans = val; diff = abs(val-t); ansL = min(Nodes[l].id+1,Nodes[r].id+1); ansR = max(Nodes[l].id, Nodes[r].id); } if(val > t) l++; else if(val < t) r++; else break; if(l == r) r++; } cout << ans << " " << ansL << " " << ansR << "\n"; } } return 0; }View Code