題目大意:
3<=m<=n<=1e5
題解:
顯然是C由小到大是最優的,那麼這時代價就是(最大-最小)*2
先把把所有蛋糕按c排序。
不然發現隨着左端點的遞增,最優決策的右端點是非遞減的。
然後這個東西居然可以分治???(套路太淺)
設表示現在要搞左端點在裏的,它們可能的最優決策區間是
設,m的最優決策點是u,這個可以通過暴力掃描得到。
那麼
假設query一次的複雜度是的,那麼這個做法的複雜度是的。
可以這麼分析,每一層的query次數最多是的,一共有層
query可以通過預處理一個主席樹來線段樹二分前V前大的和來做
總複雜度是
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int N = 2e5 + 5;
int n, m;
struct P {
ll x, y;
P(ll _x = 0, ll _y = 0) { x = _x, y = _y;}
} a[N];
int cmp(P a, P b) { return a.y < b.y;}
P operator + (P a, P b) { return P(a.x + b.x, a.y + b.y);}
P operator - (P a, P b) { return P(a.x - b.x, a.y - b.y);}
int b[N], tb[N];
int cmp2(int x, int y) { return a[x].x < a[y].x;}
struct tree {
int l, r;
P a;
} t[N * 30];
#define i0 t[i].l
#define i1 t[i].r
int g[N], pl, pr, tot;
void add(int &i, int x, int y) {
if(y < pl || x > pr) return;
t[++ tot] = t[i]; i = tot;
if(x >= pl && y <= pr) {
t[i].a = P(1, a[b[x]].x);
return;
}
int m = x + y >> 1;
add(i0, x, m); add(i1, m + 1, y);
t[i].a = t[i0].a + t[i1].a;
}
P px;
void ft(int g1, int g2, int x, int y) {
if(x == y) {
if(pl - px.x > 0) px = px + t[g2].a - t[g1].a;
return;
}
int m = x + y >> 1;
int r1 = t[g1].r, r2 = t[g2].r;
if((t[r2].a - t[r1].a).x <= pl - px.x) {
px = px + t[r2].a - t[r1].a;
ft(t[g1].l, t[g2].l, x, m);
} else ft(r1, r2, m + 1, y);
}
ll query(int x, int y) {
px = P(0, 0); pl = m - 2;
ft(g[x], g[y - 1], 1, n);
return px.y + -2 * (a[y].y - a[x].y) + a[x].x + a[y].x;
}
ll ans = -1e18;
void dg(int x, int y, int l, int r) {
if(x > y) return;
if(x == y) {
fo(i, l, r) if(x + m - 1 <= i)
ans = max(ans, query(x, i));
return;
}
int mi = x + y >> 1;
int st = max(l, mi + m - 1);
if(st > r) {
dg(x, mi - 1, l, r);
return;
}
int u = st; ll v = query(mi, u);
fo(i, st + 1, r) {
ll v2 = query(mi, i);
if(v2 > v) u = i, v = v2;
}
ans = max(ans, v);
dg(x, mi - 1, l, u);
dg(mi + 1, y, u, r);
}
int main() {
freopen("cake3.in", "r", stdin);
freopen("cake3.out", "w", stdout);
scanf("%d %d", &n, &m);
fo(i, 1, n) scanf("%lld %lld", &a[i].x, &a[i].y);
sort(a + 1, a + n + 1, cmp);
fo(i, 1, n) b[i] = i;
sort(b + 1, b + n + 1, cmp2);
fo(i, 1, n) tb[b[i]] = i;
fo(i, 1, n) {
g[i] = g[i - 1];
pl = pr = tb[i];
add(g[i], 1, n);
}
dg(1, n, 1, n);
pp("%lld\n", ans);
}