#include <cstdio> #include <algorithm> using std::printf; using std::scanf; using std::sort; using std::upper_bound; using std::lower_bound; struct Interval { long long day; int fromId; int toId; long long height; }; long long growths[500001]; long long cummulatedGrowths[500001]; Interval intervals[500001]; int intervalsLength; int n, m; long long d, h; int intervalsLower(const int, const Interval & interval) { long long days = d - interval.day; long long endHeight = interval.height + days * growths[interval.toId - 1]; return h <= endHeight ? 1 : 0; } long long countWeight(int fromIndex, int toIndex, const Interval * interval) { long long days = d - interval->day; int count = toIndex - fromIndex; return (cummulatedGrowths[fromIndex] - cummulatedGrowths[toIndex]) * days + (interval->height - h) * count; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%lld", growths + i); sort(growths, growths + n); cummulatedGrowths[n] = 0; for (int i = n - 1; i >= 0; i--) cummulatedGrowths[i] = growths[i] + cummulatedGrowths[i + 1]; intervals[0].day = 0; intervals[0].fromId = 0; intervals[0].toId = n; intervals[0].height = 0; intervalsLength = 1; for (int di = 0; di < m; di++) { scanf("%lld%lld", &d, &h); Interval * foundPtr = upper_bound(intervals, intervals + intervalsLength, 0, intervalsLower); int foundIndex = foundPtr - intervals; if (foundIndex == intervalsLength) { printf("0\n"); continue; } //foundPtr->height + (d - foundPtr->day) * x >= h long long searchedHeight = (h - foundPtr->height) / (d - foundPtr->day); if ((h - foundPtr->height) % (d - foundPtr->day) > 0) searchedHeight++; long long * foundGrowth = lower_bound(growths + foundPtr->fromId, growths + foundPtr->toId, searchedHeight); int foundGrowthIndex = foundGrowth - growths; long long weightSum = 0; weightSum += countWeight(foundGrowthIndex, foundPtr->toId, foundPtr); for (int ii = foundIndex + 1; ii < intervalsLength; ii++) weightSum += countWeight(intervals[ii].fromId, intervals[ii].toId, intervals + ii); printf("%lld\n", weightSum); if (foundGrowthIndex == foundPtr->fromId) { foundPtr->day = d; foundPtr->height = h; foundPtr->toId = n; intervalsLength = foundIndex + 1; } else { foundPtr->toId = foundGrowthIndex; Interval * nextPtr = foundPtr + 1; nextPtr->day = d; nextPtr->height = h; nextPtr->fromId = foundGrowthIndex; nextPtr->toId = n; intervalsLength = foundIndex + 2; } } return 0; }
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 | #include <cstdio> #include <algorithm> using std::printf; using std::scanf; using std::sort; using std::upper_bound; using std::lower_bound; struct Interval { long long day; int fromId; int toId; long long height; }; long long growths[500001]; long long cummulatedGrowths[500001]; Interval intervals[500001]; int intervalsLength; int n, m; long long d, h; int intervalsLower(const int, const Interval & interval) { long long days = d - interval.day; long long endHeight = interval.height + days * growths[interval.toId - 1]; return h <= endHeight ? 1 : 0; } long long countWeight(int fromIndex, int toIndex, const Interval * interval) { long long days = d - interval->day; int count = toIndex - fromIndex; return (cummulatedGrowths[fromIndex] - cummulatedGrowths[toIndex]) * days + (interval->height - h) * count; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%lld", growths + i); sort(growths, growths + n); cummulatedGrowths[n] = 0; for (int i = n - 1; i >= 0; i--) cummulatedGrowths[i] = growths[i] + cummulatedGrowths[i + 1]; intervals[0].day = 0; intervals[0].fromId = 0; intervals[0].toId = n; intervals[0].height = 0; intervalsLength = 1; for (int di = 0; di < m; di++) { scanf("%lld%lld", &d, &h); Interval * foundPtr = upper_bound(intervals, intervals + intervalsLength, 0, intervalsLower); int foundIndex = foundPtr - intervals; if (foundIndex == intervalsLength) { printf("0\n"); continue; } //foundPtr->height + (d - foundPtr->day) * x >= h long long searchedHeight = (h - foundPtr->height) / (d - foundPtr->day); if ((h - foundPtr->height) % (d - foundPtr->day) > 0) searchedHeight++; long long * foundGrowth = lower_bound(growths + foundPtr->fromId, growths + foundPtr->toId, searchedHeight); int foundGrowthIndex = foundGrowth - growths; long long weightSum = 0; weightSum += countWeight(foundGrowthIndex, foundPtr->toId, foundPtr); for (int ii = foundIndex + 1; ii < intervalsLength; ii++) weightSum += countWeight(intervals[ii].fromId, intervals[ii].toId, intervals + ii); printf("%lld\n", weightSum); if (foundGrowthIndex == foundPtr->fromId) { foundPtr->day = d; foundPtr->height = h; foundPtr->toId = n; intervalsLength = foundIndex + 1; } else { foundPtr->toId = foundGrowthIndex; Interval * nextPtr = foundPtr + 1; nextPtr->day = d; nextPtr->height = h; nextPtr->fromId = foundGrowthIndex; nextPtr->toId = n; intervalsLength = foundIndex + 2; } } return 0; } |