[ABC351E] Jump Distance Sum

一道 tang problem,浪费我大半个下午,使我十分痛苦,呜呜呜呜。

题意概括

我们有 \(N\) 个点,要求 \(\sum_{i=1}^{N-1}\sum_{j=i+1}^{N}dis(P_i,P_j)\)

\(P_i\) 指的是第 \(i\) 个点。

我们定义 \(dis(P_i,P_j)\) 为从 \(P_i\)\(P_j\) 的最小操作次数。

关于操作,我们假设现在处于 \((x,y)\),我们可以到达 \((x+1,y+1)\)\((x+1,y-1)\)\((x-1,y+1)\)\((x-1,y-1)\)

就是这个亚子。

杂技吧做?

怎么办!!!怎么办!!!怎么办!!!

劳资根本不会呜呜呜呜。

我们先考虑一下一个 \(dis\) 怎么求,不然暴力都不行。

我去理性思考了一波,有的点直接确实没法到达,我们从图上难以分析。

这个问题就是 \((x_i-x_j,y_i-y_j)\),我们可以选择去每一次将这么两个数任何一个加一或者减一。

我们惊人的发现了一个秘密的事情,辣就是这个东西如果加起来是偶数才行,主要是这个东西总体上不变或者加二减二。

所以我们按照 \(x+y\) 的奇偶性分成两类。

这样我们就能在每一类上求出来可能的贡献了。

对于两个,这个贡献是 \(max(|x_1-x_2|,|y_1-y_2|)\)

所以我们起码会暴力了,但是我不到这个怎么搞正解......

所以我们去看一看这个东西是什么玩意。

所有的问题其实就在这 \(max\) 上了,有这个东西就让我很绝望,所以我发现了世界的真相。

这个东西不就是切比雪夫距离嘛!!!

大家都知道,切比雪夫距离和曼哈顿距离是阔以相互转化的。

放一下怎么转化,防止之后我忘掉......

\((x,y)\to(x+y,x-y)\),原坐标中曼哈顿距离等于新坐标中切比雪夫距离。

\((x,y)\to(\frac{x+y}{2},\frac{x-y}{2})\),原坐标中切比雪夫距离等于新坐标中曼哈顿距离。

我们就直接转换,这个/2到最后处理,因为我们不方便搞小数。

就这么转化一波,问题就是求到所有点的曼哈顿距离就行了。

wow,没辣。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MN=1e6+116;
int n, ans=0;
vector <int> vec[4];
signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin>>n;
	for(int i=1,x,y; i<=n; ++i){
		cin>>x>>y;
		if((x+y)%2==0){
			vec[0].push_back(x+y);
			vec[1].push_back(x-y);
		}else{
			vec[2].push_back(x+y);
			vec[3].push_back(x-y);
		}
	}
	for(int i=0; i<4; ++i){
		sort(vec[i].begin(),vec[i].end());
		int siz=vec[i].size();
		for(int j=0; j<siz; ++j){
			ans+=vec[i][j]*(2*j+1-siz);
		}
	}
	cout<<ans/2<<'\n';
	return 0;
}
posted @ 2025-08-20 20:45  BaiBaiShaFeng  阅读(8)  评论(0)    收藏  举报
Sakana Widget右下角定位