#pragma GCC optimize("O2") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define int ll #define INT128_MAX (__int128)(((unsigned __int128) 1 << ((sizeof(__int128) * __CHAR_BIT__) - 1)) - 1) #define INT128_MIN (-INT128_MAX - 1) namespace R = std::ranges; namespace V = std::views; using namespace std; using ll = long long; using ull = unsigned long long; using pii = pair; using pll = pair; using tiii = tuple; using ldb = long double; //#define double ldb template ostream& operator<<(ostream& os, const pair pr) { return os << pr.first << ' ' << pr.second; } template ostream& operator<<(ostream& os, const array &arr) { for(const T &X : arr) os << X << ' '; return os; } template ostream& operator<<(ostream& os, const vector &vec) { for(const T &X : vec) os << X << ' '; return os; } using frac = array; bool operator<=(frac a, frac b) { if (a[0] - b[0] >= 0) return a[0] * b[1] <= a[1] * b[0]; else return a[0] * b[1] >= a[1] * b[0]; } frac inter(frac a, frac b) { if (a[0] > b[0]) return {b[1] - a[1], a[0] - b[0]}; else return {a[1] - b[1], b[0] - a[0]}; } signed main() { ios::sync_with_stdio(false), cin.tie(NULL); int n, m; cin >> n >> m; vector a(n), d(n); for(int i = 0; i < n; i++) cin >> a[i] >> d[i]; if (R::min(d) >= 0) { int ans = LLONG_MIN; for(int i = 0; i < n; i++) ans = max(ans, m * a[i] + m * (m - 1) / 2 * d[i]); cout << ans << '\n'; return 0; } vector s(1, 0); { priority_queue> pq; vector k(n); for(int i = 0; i < n; i++) { if (d[i] < 0) { pq.push({a[i], i}); k[i] = 1; } } for(int i = 0; i < m; i++) { auto [val, id] = pq.top(); pq.pop(); s.emplace_back(val); pq.push({a[id] + k[id] * d[id], id}); k[id]++; } partial_sum(s.begin(), s.end(), s.begin()); } if (R::max(d) < 0) { cout << s[m] << '\n'; return 0; } vector> l; for(int i = 0; i < n; i++) if (d[i] >= 0) l.push_back({d[i], 2 * a[i] - d[i]}); R::sort(l); deque> cht; for(int i = 1; i <= ssize(l); i++) { if (i == ssize(l) or l[i - 1][0] != l[i][0]) { while(ssize(cht) >= 2 and inter(l[i - 1], end(cht)[-2]) <= inter(end(cht)[-2], end(cht)[-1])) cht.pop_back(); cht.push_back(l[i - 1]); } } int ans = LLONG_MIN; for(int k = 0; k <= m; k++) { //while(ssize(cht) >= 2 and inter(cht[0], cht[1]) <= frac{k, 1}) while(ssize(cht) >= 2 and inter(cht[0], cht[1])[0] <= inter(cht[0], cht[1])[1] * k) cht.pop_front(); int eval = k * cht.front()[0] + cht.front()[1]; ans = max(ans, eval * k / 2 + s[m - k]); } cout << ans << '\n'; return 0; }