All modern mobile applications are divided into free and paid. Even a single application developers often release two versions: a paid version without ads and a free version with ads.
Suppose that a paid version of the app costs p ( p is an integer) rubles, and the free version of the application contains c ad banners. Each user can be described by two integers: a i — the number of rubles this user is willing to pay for the paid version of the application, and b i — the number of banners he is willing to tolerate in the free version.
The behavior of each member shall be considered strictly deterministic:
- if for user i, value b i is at least c, then he uses the free version,
- otherwise, if value a i is at least p, then he buys the paid version without advertising,
- otherwise the user simply does not use the application.
Each user of the free version brings the profit of c × w rubles. Each user of the paid version brings the profit of p rubles.
Your task is to help the application developers to select the optimal parameters p and c. Namely, knowing all the characteristics of users, for each value of c from 0 to (max b i) + 1 you need to determine the maximum profit from the application and the corresponding parameter p.
Input
The first line contains two integers n and w (1 ≤ n ≤ 105; 1 ≤ w ≤ 105) — the number of users and the profit from a single banner. Each of the next n lines contains two integers a i and b i (0 ≤ a i, b i ≤ 105) — the characteristics of the i-th user.
Output
Print (max b i) + 2 lines, in the i-th line print two integers: pay — the maximum gained profit at c = i - 1, p (0 ≤ p ≤ 109) — the corresponding optimal app cost. If there are multiple optimal solutions, print any of them.
Examples
input
2 1
2 0
0 2
output
0 3
3 2
4 2
2 2
input
3 1
3 1
2 2
1 3
output
0 4
3 4
7 3
7 2
4 2
Solution:
#include <cstring> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <memory.h> #include <cassert> using namespace std; const int MAX = 100200; const int BLOCK_SIZE = 300; const int BLOCK_CNT = MAX / BLOCK_SIZE; pair <int, int> user[MAX]; int sz[BLOCK_CNT]; int st[BLOCK_CNT][BLOCK_SIZE + 10]; long double sx[BLOCK_CNT][BLOCK_SIZE + 10]; int ptr[BLOCK_CNT]; long long bmax[BLOCK_CNT]; int bid[BLOCK_CNT]; int badd[BLOCK_CNT]; int a[MAX]; long double intersect(int i, int j) { return 1.0 * ((long long)i * a[i] - (long long)j * a[j]) / (j - i); } long long pay[MAX]; int opt[MAX]; int main() { int n, w; scanf("%d %d", &n, &w); for (int i = 0; i < n; i++) { scanf("%d %d", &user[i].second, &user[i].first); } sort(user, user + n); int maxbi = user[n - 1].first; for (int i = 0; i < MAX; i++) { a[i] = 0; } for (int b = 0; b < BLOCK_CNT; b++) { bmax[b] = 0; bid[b] = b * BLOCK_SIZE; badd[b] = 0; } int j = 0; for (int C = 0; C <= maxbi + 1; C++) { while (j < n) { if (user[j].first >= C) { break; } int pos = user[j].second; for (int b = 0; b < BLOCK_CNT; b++) { int from = b * BLOCK_SIZE; int to = from + BLOCK_SIZE; if (pos >= to) { badd[b]++; while (ptr[b] < sz[b] && badd[b] > sx[b][ptr[b]]) { ptr[b]++; } int q = st[b][ptr[b]]; bmax[b] = (long long)q * (a[q] + badd[b]); bid[b] = q; } else { for (int i = from; i < to; i++) { a[i] += badd[b]; } for (int i = from; i <= pos; i++) { a[i]++; } badd[b] = 0; sz[b] = 0; for (int i = from; i < to; i++) { while (sz[b] >= 2) { long double u = intersect(i, st[b][sz[b]]); if (u < sx[b][sz[b] - 1]) { sz[b]--; } else { break; } } st[b][++sz[b]] = i; if (sz[b] >= 2) { sx[b][sz[b] - 1] = intersect(i, st[b][sz[b] - 1]); } } ptr[b] = 1; while (ptr[b] < sz[b] && 0 > sx[b][ptr[b]]) { ptr[b]++; } int q = st[b][ptr[b]]; bmax[b] = (long long)q * a[q]; bid[b] = q; break; } } j++; } pay[C] = -1; opt[C] = -1; for (int b = 0; b < BLOCK_CNT; b++) { if (bmax[b] > pay[C]) { pay[C] = bmax[b]; opt[C] = bid[b]; } } pay[C] += C * 1LL * w * (n - j); } for (int C = 0; C <= maxbi + 1; C++) { printf("%I64d %d\n", pay[C], opt[C]); } return 0; }