题目链接
首先,愚人节那天,暴力斩获30分,(暴力法真好用!
然后,讲一下解题的思路吧,主要是怎样转换切比雪夫距离这里要有神奇的方法。
首先,我们先列举一下两点间切比雪夫距离的求解公式:
指的是i、j两点的切比雪夫距离
于是,我们再用一些数学上的思维来拆解这个等式关系
这样的做法,是为了我们去掉最大值max()符号
之后,我们发现,似乎变成了新的坐标,我们移项来看
我的天呐,神不神奇?
等式右边,不就是曼哈顿距离了嘛。
只是原来的做了这样的转换
好神奇!!!
那么,原来的问题,就变成了如何求解各点到其余所有点的距离和了,二维偏序基础!
解决二维偏序问题,我们首先对第一维进行排序,就对x进行升序排序吧,然后就可以O(1)的求解其中一维了(x坐标)。
然后,利用树状数组+离散化的操作,我们处理第二维。
这样的处理方法是为了去掉绝对值,变成绝对大减去绝对小这样的形式了。
当然,主席树等数据结构,也是可以用以维护的。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, _UP;
ll sum[maxN] = {0}, all_y = 0, tx, ty;
struct node
{
ll x, y;
node(ll a=0, ll b=0):x(a), y(b) {}
inline void In()
{
scanf("%lld%lld", &tx, &ty);
x = tx + ty; y = tx - ty;
}
friend bool operator < (node e1, node e2) { return e1.x < e2.x; }
} a[maxN];
ll tree[maxN], num[maxN], Lsan[maxN];
inline void update(int x, ll val)
{
while(x <= _UP)
{
tree[x] += val;
num[x] ++;
x += lowbit(x);
}
}
inline void query(int x, ll &ss, ll &sz)
{
ss = 0; sz = 0;
while(x)
{
ss += tree[x]; sz += num[x];
x -= lowbit(x);
}
}
int main()
{
scanf("%d", &N);
for(int i=1; i<=N; i++) { a[i].In(); Lsan[i] = a[i].y; }
sort(a + 1, a + N + 1);
sort(Lsan + 1, Lsan + N + 1);
_UP = (int)(unique(Lsan + 1, Lsan + N + 1) - Lsan - 1);
for(int i=1, id; i<=N; i++)
{
sum[i] = sum[i - 1] + a[i].x;
all_y += a[i].y;
id = (int)(lower_bound(Lsan + 1, Lsan + _UP + 1, a[i].y) - Lsan);
update(id, a[i].y);
}
ll ans = INF, tmp;
ll ss, sz;
for(int i=1, id; i<=N; i++)
{
tmp = (i - 1LL) * a[i].x - sum[i - 1] + (sum[N] - sum[i]) - 1LL * (N - i) * a[i].x;
id = (int)(lower_bound(Lsan + 1, Lsan + _UP + 1, a[i].y) - Lsan);
query(id, ss, sz);
tmp += sz * a[i].y - ss + all_y - ss - 1LL * (N - sz) * a[i].y;
ans = min(ans, tmp);
}
printf("%lld\n", ans >> 1LL);
return 0;
}