Gym - 101733D Triangle Construction

Little Andrey wants to work in IT. He already knows that he should exercise in mathematics and algorithms.

Andrey likes to play with a set of wooden sticks of various lengths. Experimentally he found that three sticks can form a triangle, if the length of the longest of them is strictly less than the sum of two others.

A sequence of n sticks is located on the table. Andrey chooses some interval with indices from l to r and looks for three sticks which can form a triangle.

Help Andrew, for each of the q intervals find three sticks such that he can make a triangle.

Input
The first input line contains two integers n and q (1 ≤ n, q ≤ 300 000), number of sticks and number of intervals. The second line contains n integers li (1 ≤ li ≤ 1018), the array of sticks length in the order they lie on the table.

Each of the next q lines contains two integers l and r (1 ≤ l ≤ r ≤ n), the interval boundaries.

Output
For each interval print any three different indices i j k (l ≤ i, j, k ≤ r) such that sticks with lengths li lj lk make a triangle. If there are no such indices, output the only number  - 1.

Example
Input
5 3
1 3 1 3 1
1 3
2 4
1 5
Output
-1
2 3 4
1 3 5

给出一段数字和几个查询,问查询的范围内有没有三条边能构成三角形。根据定理两边之和大于最长边能构造三角形,先把截取部分排序(由于题目要求输出索引,所以这里还要打个数据结构来记录索引),然后按顺序把前两条边加起来,比较是否大于第三边。

test5疯狂超时…..,队友认为test5很大可能是最坏情况(排序后变成斐波那契数列)。如果是最坏情况的话,可能是无解的。但是斐波那契数列持续增长,到了88位已经超出了题目的数据上限,所以连续斐波那契数列最多持续88个!88个之后只能是有解的其他数列。所以可以取巧的针对优化一发:

if (b - a > 88) {
    b = a + 88;
}

大于88个直接跳到89…..可以说是非常针对性的“优化”了。然后test5果然就低空飞过了……

ac代码:

public class Main {
    public static void main(String[] args) {
        //下面的reader是自己造的bufferedReader轮子,就不贴了
        PrintWriter out = new PrintWriter(System.out);
        int n = reader.nextInt();
        int q = reader.nextInt();
        if (n < 3) {
            while (q-- > 0) {
                System.out.println(-1);
            }
            return;
        }
        long[] list = new long[n + 5];
        for (int i = 1; i <= n; i++) {
            list[i] = reader.nextLong();
        }
        while (q-- > 0) {
            int a = reader.nextInt();
            int b = reader.nextInt();
            if (b - a > 88) {
                b = a + 88;
            }
            ArrayList check = new ArrayList();
            for (int i = a; i <= b; i++) {
                check.add(new Pair(list[i], i));
            }
            Collections.sort(check);
            boolean canMake = false;
            for (int i = 2, len = check.size(); i < len; i++) {
                canMake = check.get(i - 2).first + check.get(i - 1).first > check.get(i).first;
                if (canMake) {
                    out.println(check.get(i - 2).second + " " + check.get(i - 1).second + " " + check.get(i).second);
                    break;
                }
            }
            if (!canMake) {
                out.println(-1);
            }
        }
        out.close();
    }
}

class Pair implements Comparable {
    long first;
    long second;

    public Pair(long first, long second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public int compareTo(Pair o) {
        if (this.first > o.first) {
            return 1;
        } else if (this.first < o.first) {
            return -1;
        }
        return 0;
    }
}

你可能感兴趣的:(Java,ACM,思维)