import java.util.Arrays; import java.util.LinkedList; import java.util.Scanner; public class sia { public static void main(String[] args) { // reading input Scanner scanner = new Scanner(System.in); long fieldCount = scanner.nextLong(); long harvestCount = scanner.nextLong(); long[] speeds = new long[(int) fieldCount]; for (int i = 0; i < fieldCount; i++) { speeds[i] = scanner.nextLong(); } // preparing Arrays.sort(speeds); long[] speedIntegrations = new long[(int) fieldCount + 1]; speedIntegrations[0] = 0; for (int i = 1; i < fieldCount + 1; i++) { speedIntegrations[i] = speedIntegrations[i - 1] + speeds[i - 1]; } LinkedList<long[]> positionDayHeights = new LinkedList<>(); positionDayHeights.add(new long[] { 0L, 0L, 0L }); // solving for (int i = 0; i < harvestCount; i++) { long day = scanner.nextLong(); long height = scanner.nextLong(); long harvested = 0; long sawPosition = fieldCount; while (!positionDayHeights.isEmpty()) { long[] last = positionDayHeights.getLast(); long position = last[0]; long pastDay = last[1]; long pastHeight = last[2]; long duration = day - pastDay; long speed = speeds[(int) position]; long currentHeight = pastHeight + duration * speed; if (height <= currentHeight) { long harvestedPerDay = speedIntegrations[(int) sawPosition] - speedIntegrations[(int) position]; harvested += harvestedPerDay * duration; harvested -= (sawPosition - position) * (height - pastHeight); sawPosition = position; positionDayHeights.removeLast(); } else { break; } } if (!positionDayHeights.isEmpty()) { long[] last = positionDayHeights.getLast(); long badPosition = last[0]; long goodPosition = sawPosition; long pastDay = last[1]; long pastHeight = last[2]; while (goodPosition - badPosition > 1) { long bisect = (goodPosition + badPosition) / 2; long duration = (day - pastDay); long speed = speeds[(int) bisect]; long currentHeight = pastHeight + duration * speed; if (height < currentHeight) { long harvestedPerDay = speedIntegrations[(int) goodPosition] - speedIntegrations[(int) bisect]; harvested += harvestedPerDay * duration; harvested -= (goodPosition - bisect) * (height - pastHeight); goodPosition = bisect; } else { badPosition = bisect; } } if (goodPosition != fieldCount) { positionDayHeights.add(new long[] { goodPosition, day, height }); } } else { positionDayHeights.add(new long[] { 0, day, height }); } System.out.println(harvested); } scanner.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 | import java.util.Arrays; import java.util.LinkedList; import java.util.Scanner; public class sia { public static void main(String[] args) { // reading input Scanner scanner = new Scanner(System.in); long fieldCount = scanner.nextLong(); long harvestCount = scanner.nextLong(); long[] speeds = new long[(int) fieldCount]; for (int i = 0; i < fieldCount; i++) { speeds[i] = scanner.nextLong(); } // preparing Arrays.sort(speeds); long[] speedIntegrations = new long[(int) fieldCount + 1]; speedIntegrations[0] = 0; for (int i = 1; i < fieldCount + 1; i++) { speedIntegrations[i] = speedIntegrations[i - 1] + speeds[i - 1]; } LinkedList<long[]> positionDayHeights = new LinkedList<>(); positionDayHeights.add(new long[] { 0L, 0L, 0L }); // solving for (int i = 0; i < harvestCount; i++) { long day = scanner.nextLong(); long height = scanner.nextLong(); long harvested = 0; long sawPosition = fieldCount; while (!positionDayHeights.isEmpty()) { long[] last = positionDayHeights.getLast(); long position = last[0]; long pastDay = last[1]; long pastHeight = last[2]; long duration = day - pastDay; long speed = speeds[(int) position]; long currentHeight = pastHeight + duration * speed; if (height <= currentHeight) { long harvestedPerDay = speedIntegrations[(int) sawPosition] - speedIntegrations[(int) position]; harvested += harvestedPerDay * duration; harvested -= (sawPosition - position) * (height - pastHeight); sawPosition = position; positionDayHeights.removeLast(); } else { break; } } if (!positionDayHeights.isEmpty()) { long[] last = positionDayHeights.getLast(); long badPosition = last[0]; long goodPosition = sawPosition; long pastDay = last[1]; long pastHeight = last[2]; while (goodPosition - badPosition > 1) { long bisect = (goodPosition + badPosition) / 2; long duration = (day - pastDay); long speed = speeds[(int) bisect]; long currentHeight = pastHeight + duration * speed; if (height < currentHeight) { long harvestedPerDay = speedIntegrations[(int) goodPosition] - speedIntegrations[(int) bisect]; harvested += harvestedPerDay * duration; harvested -= (goodPosition - bisect) * (height - pastHeight); goodPosition = bisect; } else { badPosition = bisect; } } if (goodPosition != fieldCount) { positionDayHeights.add(new long[] { goodPosition, day, height }); } } else { positionDayHeights.add(new long[] { 0, day, height }); } System.out.println(harvested); } scanner.close(); } } |