제출 #768377

#제출 시각아이디문제언어결과실행 시간메모리
768377minhcoolCake 3 (JOI19_cake3)C++17
100 / 100
1221 ms21952 KiB
#define local #ifndef local #include "" #endif #include<bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; using namespace std; #define int long long #define fi first #define se second #define pb push_back #define mp make_pair typedef pair<int, int> ii; typedef pair<ii, int> iii; typedef pair<ii, ii> iiii; const int N = 3e5 + 5; const int oo = 1e18 + 7, mod = 1e9 + 7; mt19937 rng(1); int rnd(int l, int r){ int temp = rng() % (r - l + 1); return abs(temp) + l; } int n, m; ii arr[N]; int v[N], c[N]; int answer = -oo; vector<int> diff; int pos[N]; bool cmp(ii a, ii b){ return a.se < b.se; } int lstl, lstr; int sum[N << 2], num[N << 2]; int IT[N << 2]; void upd(int id, int l, int r, int pos, int val){ if(l == r){ sum[id] += diff[l] * val; num[id] += val; return; } int mid = (l + r) >> 1; if(pos <= mid) upd(id << 1, l, mid, pos, val); else upd(id << 1 | 1, mid + 1, r, pos, val); sum[id] = sum[id << 1] + sum[id << 1 | 1]; num[id] = num[id << 1] + num[id << 1 | 1]; } int tol(int id, int l, int r, int rem){ if(l == r){ if(rem > num[id]) return -oo; return rem * diff[l]; } int mid = (l + r) >> 1; if(num[id << 1] >= rem) return tol(id << 1, l, mid, rem); else return sum[id << 1] + tol(id << 1 | 1, mid + 1, r, rem - num[id << 1]); } void mov(int le, int ri){ while(lstl > le){ lstl--; upd(1, 1, diff.size() - 1, pos[lstl], 1); } while(lstr < ri){ lstr++; upd(1, 1, diff.size() - 1, pos[lstr], 1); } while(lstl < le){ upd(1, 1, diff.size() - 1, pos[lstl], -1); lstl++; } while(lstr > ri){ upd(1, 1, diff.size() - 1, pos[lstr], -1); lstr--; } } int get(){ return tol(1, 1, diff.size() - 1, m - 2); } void dncdp(int l, int r, int optl, int optr){ if(l > r) return; int temp1 = lstl, temp2 = lstr; if(optl == optr){ for(int i = l; i <= r; i++){ mov(optl + 1, i - 1); // cout << optl << " " << i << "\n"; answer = max(answer, get() + v[optl] + 2 * c[optl] + v[i] - 2 * c[i]); } return; } int mid = (l + r) >> 1; ii maxi = {-oo, -oo}; for(int i = optl; (i <= optr) && ((i + 2) <= mid); i++){ mov(i + 1, mid - 1); maxi = max(maxi, {get() + v[i] + 2 * c[i] + v[mid] - 2 * c[mid], i}); } //cout << maxi.se << " " << mid << "\n"; answer = max(answer, maxi.fi); dncdp(l, mid - 1, optl, maxi.se); dncdp(mid + 1, r, maxi.se, optr); mov(temp1, temp2); } #ifdef local void process(){ cin >> n >> m; for(int i = 1; i <= n; i++) cin >> arr[i].fi >> arr[i].se; sort(arr + 1, arr + n + 1, cmp); for(int i = 1; i <= n; i++){ v[i] = arr[i].fi; c[i] = arr[i].se; } diff.pb(oo); for(int i = 1; i <= n; i++) diff.pb(arr[i].fi); sort(diff.begin(), diff.end()); diff.resize(unique(diff.begin(), diff.end()) - diff.begin()); reverse(diff.begin(), diff.end()); for(int i = 1; i <= n; i++){ int le = 1, ri = diff.size() - 1; while(le < ri){ int mid = (le + ri) >> 1; if(diff[mid] > v[i]) le = mid + 1; else ri = mid; } pos[i] = le; } lstl = 1, lstr = 0; dncdp(m, n, 1, n - m + 1); cout << answer; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); process(); } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...