[TJOI2013]松鼠聚会【切比雪夫距离转换曼哈顿距离】

Lara ·
更新时间:2024-11-14
· 555 次阅读

题目链接

  首先,愚人节那天,暴力斩获30分,(暴力法真好用!

  然后,讲一下解题的思路吧,主要是怎样转换切比雪夫距离这里要有神奇的方法。

首先,我们先列举一下两点间切比雪夫距离的求解公式:

Qdis(1, 2) = max(abs(x_1 - x_2), abs(y_1 - y_2))

Qdis(i, j)指的是i、j两点的切比雪夫距离

于是,我们再用一些数学上的思维来拆解这个等式关系

max(abs(x_1 - x_2), abs(y_1 - y_2)) = \frac{1}{2} \left [ abs(x_1 - x_2 + y_1 - y_2) + abs(x_1 - x_2 - y_1 + y_2) \right ]

这样的做法,是为了我们去掉最大值max()符号

之后,我们发现,似乎变成了新的坐标,我们移项来看

abs(x_1 - x_2 + y_1 - y_2) + abs(x_1 - x_2 - y_1 + y_2) = abs(x_1 + y_1 - (x_2 + y_2)) + abs(x_1 - y_1 + (x_2 - y_2))

我的天呐,神不神奇?

等式右边,不就是曼哈顿距离了嘛。

只是原来的(x, y)\rightarrow (\frac{x + y}{2}, \frac{x - y}{2})做了这样的转换

好神奇!!!

那么,原来的问题,就变成了如何求解各点到其余所有点的距离和了,二维偏序基础!

解决二维偏序问题,我们首先对第一维进行排序,就对x进行升序排序吧,然后就可以O(1)的求解其中一维了(x坐标)。

然后,利用树状数组+离散化的操作,我们处理第二维。

这样的处理方法是为了去掉绝对值,变成绝对大减去绝对小这样的形式了。

当然,主席树等数据结构,也是可以用以维护的。

#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #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> 1LL); return 0; }
作者:Andres_Lionel



曼哈顿 松鼠 曼哈顿距离

需要 登录 后方可回复, 如果你还没有账号请 注册新账号