import java.math.BigInteger; import java.util.Arrays; import java.util.Scanner; import java.util.Stack; class Range { private int begin; private int end; private long lastDay; private long lastHeight; public Range(int begin, int end) { this.begin = begin; this.end = end; } public long getLastDay() { return lastDay; } public long getLastHeight() { return lastHeight; } public void setLastDay(long lastDay) { this.lastDay = lastDay; } public void setLastHeight(long lastHeight) { this.lastHeight = lastHeight; } public int getBegin() { return begin; } public int getEnd() { return end; } public void setBegin(int begin) { this.begin = begin; } public void setEnd(int end) { this.end = end; } } public class sia { static long[] heights; static long[] cummulated; public static int find(int begin, int end, long days, long height) { if (begin >= end) return days * heights[end] <= height ? end + 1 : end; int mid = (begin + end) / 2; if (days * heights[mid] <= height) return find(mid + 1, end, days, height); return find(begin, mid - 1, days, height); } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int m = in.nextInt(); heights = new long[n]; for (int i = 0; i < n; i++) heights[i] = in.nextLong(); Arrays.sort(heights); cummulated = new long[n + 1]; cummulated[n] = 0; for (int i = n - 1; i >= 0; i--) cummulated[i] = heights[i] + cummulated[i + 1]; Stack<Range> ranges = new Stack<Range>(); ranges.add(new Range(0, n - 1)); for (int i = 0; i < m; i++) { long di = in.nextLong(); long bi = in.nextLong(); boolean shouldSearch = true; long result = 0; while (shouldSearch) { Range range = ranges.pop(); if ((di - range.getLastDay()) * heights[range.getBegin()] < bi - range.getLastHeight()) { int position = find(range.getBegin(), range.getEnd(), di - range.getLastDay(), bi - range.getLastHeight()); if (position <= range.getEnd()) { BigInteger tmp = BigInteger.valueOf(cummulated[position] - cummulated[range.getEnd() + 1]); tmp = tmp.multiply(BigInteger.valueOf(di - range.getLastDay())); tmp = tmp.add(BigInteger.valueOf(range.getLastHeight()) .multiply( BigInteger.valueOf(range.getEnd() - position + 1))); tmp = tmp.subtract(BigInteger.valueOf(bi).multiply( BigInteger.valueOf(range.getEnd() - position + 1))); result += tmp.longValue(); range.setEnd(position-1); ranges.add(range); Range newRange = new Range(position, n-1); newRange.setLastDay(di); newRange.setLastHeight(bi); ranges.add(newRange); } else { ranges.add(range); if(range.getEnd()<n-1) { Range newRange = new Range(range.getEnd()+1, n-1); newRange.setLastDay(di); newRange.setLastHeight(bi); ranges.add(newRange); } } shouldSearch=false; } else { BigInteger tmp = BigInteger.valueOf(cummulated[range .getBegin()] - cummulated[range.getEnd() + 1]); tmp = tmp.multiply(BigInteger.valueOf(di - range.getLastDay())); tmp = tmp.add(BigInteger.valueOf(range.getLastHeight()).multiply( BigInteger.valueOf(range.getEnd() - range.getBegin() + 1))); tmp = tmp.subtract(BigInteger.valueOf(bi).multiply( BigInteger.valueOf(range.getEnd() - range.getBegin() + 1))); result += tmp.longValue(); if (ranges.isEmpty()) { shouldSearch = false; range.setBegin(0); range.setEnd(n - 1); range.setLastDay(di); range.setLastHeight(bi); ranges.add(range); } } } System.out.println(result); } in.close(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | import java.math.BigInteger; import java.util.Arrays; import java.util.Scanner; import java.util.Stack; class Range { private int begin; private int end; private long lastDay; private long lastHeight; public Range(int begin, int end) { this.begin = begin; this.end = end; } public long getLastDay() { return lastDay; } public long getLastHeight() { return lastHeight; } public void setLastDay(long lastDay) { this.lastDay = lastDay; } public void setLastHeight(long lastHeight) { this.lastHeight = lastHeight; } public int getBegin() { return begin; } public int getEnd() { return end; } public void setBegin(int begin) { this.begin = begin; } public void setEnd(int end) { this.end = end; } } public class sia { static long[] heights; static long[] cummulated; public static int find(int begin, int end, long days, long height) { if (begin >= end) return days * heights[end] <= height ? end + 1 : end; int mid = (begin + end) / 2; if (days * heights[mid] <= height) return find(mid + 1, end, days, height); return find(begin, mid - 1, days, height); } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int m = in.nextInt(); heights = new long[n]; for (int i = 0; i < n; i++) heights[i] = in.nextLong(); Arrays.sort(heights); cummulated = new long[n + 1]; cummulated[n] = 0; for (int i = n - 1; i >= 0; i--) cummulated[i] = heights[i] + cummulated[i + 1]; Stack<Range> ranges = new Stack<Range>(); ranges.add(new Range(0, n - 1)); for (int i = 0; i < m; i++) { long di = in.nextLong(); long bi = in.nextLong(); boolean shouldSearch = true; long result = 0; while (shouldSearch) { Range range = ranges.pop(); if ((di - range.getLastDay()) * heights[range.getBegin()] < bi - range.getLastHeight()) { int position = find(range.getBegin(), range.getEnd(), di - range.getLastDay(), bi - range.getLastHeight()); if (position <= range.getEnd()) { BigInteger tmp = BigInteger.valueOf(cummulated[position] - cummulated[range.getEnd() + 1]); tmp = tmp.multiply(BigInteger.valueOf(di - range.getLastDay())); tmp = tmp.add(BigInteger.valueOf(range.getLastHeight()) .multiply( BigInteger.valueOf(range.getEnd() - position + 1))); tmp = tmp.subtract(BigInteger.valueOf(bi).multiply( BigInteger.valueOf(range.getEnd() - position + 1))); result += tmp.longValue(); range.setEnd(position-1); ranges.add(range); Range newRange = new Range(position, n-1); newRange.setLastDay(di); newRange.setLastHeight(bi); ranges.add(newRange); } else { ranges.add(range); if(range.getEnd()<n-1) { Range newRange = new Range(range.getEnd()+1, n-1); newRange.setLastDay(di); newRange.setLastHeight(bi); ranges.add(newRange); } } shouldSearch=false; } else { BigInteger tmp = BigInteger.valueOf(cummulated[range .getBegin()] - cummulated[range.getEnd() + 1]); tmp = tmp.multiply(BigInteger.valueOf(di - range.getLastDay())); tmp = tmp.add(BigInteger.valueOf(range.getLastHeight()).multiply( BigInteger.valueOf(range.getEnd() - range.getBegin() + 1))); tmp = tmp.subtract(BigInteger.valueOf(bi).multiply( BigInteger.valueOf(range.getEnd() - range.getBegin() + 1))); result += tmp.longValue(); if (ranges.isEmpty()) { shouldSearch = false; range.setBegin(0); range.setEnd(n - 1); range.setLastDay(di); range.setLastHeight(bi); ranges.add(range); } } } System.out.println(result); } in.close(); } } |