Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define pb emplace_back
- using namespace std;
- using ll = long long;
- #ifdef KEV
- #define DE(i, e) cerr << #i << ' ' << i << e
- void debug(auto L, auto R) { while (L < R) cerr << *L << " \n"[L+1==R], ++L; }
- #else
- #define DE(...) 0
- void debug(...) {}
- #endif
- const int maxn = 200010, maxm = 1000010;
- const ll inf = 1ll<<55;
- ll dp[maxn];
- int cu[maxn], cd[maxn], T;
- struct bit {
- int val[maxm];
- void reset() {
- fill(val, val+maxm, 0);
- }
- bool rev = false;
- void REV(){ rev ^= true; }
- void modify(int i, int v) {
- ++i;
- if (rev) i = maxm - i;
- for (;i < maxm;i += i&-i)
- val[i] = max(val[i], v);
- }
- int query(int i) {
- ++i;
- if (rev) i = maxm - i;
- int res = 0;
- for (;i;i ^= i&-i)
- res = max(res, val[i]);
- return res;
- }
- }tree;
- int n;
- pair<int,int> loc[maxn];
- vector<int> dep[maxn];
- ll area(int a, int b) {
- return (ll)(loc[a].first-loc[b].first) * (loc[a].second-loc[b].second);
- }
- bool valid(int s, int t) {
- return loc[s].first < loc[t].first && loc[s].second < loc[t].second;
- }
- ll cal(int s, int t) {
- return valid(s, t) ? dp[s] + area(s, t) : inf;
- }
- void DC(const vector<int>& from, const vector<int>& to, int l, int r, int sl, int sr) {
- sl = max(sl, 0), sr = min(sr, (int)from.size()-1);
- auto getpos = [&](int x) {
- dp[x] = inf;
- int y = -1;
- for (int i = sl;i <= sr;++i) {
- ll nw = cal(from[i], x);
- if (nw < dp[x])
- dp[x] = nw, y = i;
- }
- // auto [X, Y] = loc[x];
- // DE(X, ' '), DE(Y, ' '), DE(dp[x], '\n');
- return y;
- };
- if (l > r) return;
- const int BUF = 1000;
- if (r-l+1 <= 500) {
- for (int i = l;i <= r;++i)
- getpos(to[i]);
- return;
- }
- if (l == r) {
- getpos(to[l]);
- return;
- }
- int m = l + r >> 1;
- int sm = getpos(to[m]);
- int A = sl, B = min(sr, sm+BUF), C = max(sl, sm-BUF), D = sr;
- DC(from, to, l, m-1, C, D);
- DC(from, to, m+1, r, A, B);
- }
- void ss(vector<int> id) {
- for (int u : id)
- dep[ cu[u] ].pb(u);
- int s = *max_element(cu, cu+n+1);
- debug(cu, cu+n+1);
- for (int i = 2;i <= s;++i) {
- DC(dep[i-1], dep[i], 0, dep[i].size()-1,
- 0, dep[i-1].size()-1);
- }
- cout << dp[n] << '\n';
- // ll res = (ll)T * (ll)T;
- // for (int u : dep[s])
- // res = min(res, dp[u]);
- // cout << res << '\n';
- }
- void solve() {
- tree.reset();
- for (int i = 0, x, y;i <= n;++i) {
- tie(x, y) = loc[i];
- DE(x, ' '), DE(y, '\n');
- cu[i] = tree.query(y) + 1;
- tree.modify(y, cu[i]);
- }
- tree.reset();
- tree.REV();
- for (int i = n, x, y;i >= 0;--i) {
- tie(x, y) = loc[i];
- cd[i] = tree.query(y) + 1;
- tree.modify(y, cd[i]);
- }
- int S = *max_element(cu, cu+n+1);
- vector<int> uf;
- DE(S, '\n');
- for (int i = 0;i <= n;++i) {
- if (cu[i] + cd[i] == S+1) {
- //cerr << cu[i] << ' ' << cd[i] << '\n';
- uf.pb(i);
- }
- }
- ss(uf);
- }
- /*
- ID: ckevin31
- LANG: C++14
- TASK:
- */
- #ifndef KEV
- inline void IO(string name) {
- freopen((name + ".in").c_str(), "r", stdin);
- freopen((name + ".out").c_str(), "w", stdout);
- }
- #else
- inline void IO(string name){}
- #endif
- signed main(){
- IO("mowing");
- ios_base::sync_with_stdio(0), cin.tie(0);
- cin >> n >> T;
- for (int i = 1;i <= n;++i)
- cin >> loc[i].first >> loc[i].second;
- ++n;
- loc[n] = {T, T};
- sort(loc, loc+n);
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement