版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/83154234
小 O 对国际象棋有着浓厚的兴趣,因为他水平高超,每次人机对战他总是轻松获胜,所 以他决定自己跟自己下国际象棋。
小 O 的棋盘非常大,达到了 ,现在他在棋盘上摆放了 n 个国王,并对你提出 了 q 次询问,每次询问指定一个坐标,问将所有国王从初始位置全部移动到这个坐标所需要 的最小步数是多少,询问之间相互独立,也就是说每次询问结束后国王会全部回到原来位置。
注意:由于小 O 担心大家无法理解过于高深的规则,所以在本题中,国王之间不会发生 相互攻击而且多个国王可以同时处在一个格子中, 国际象棋中国王一步只能移动到与其八 连通的格子中。
由于国王是可以斜着走的
所以较小的明显没有用,直接斜着走就好了。
实际答案就是切比雪夫距离。
这实际上就是模板了
我们转成曼哈顿距离,然后维护前缀和就好了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef int INT;
#define int long long
const int N=1e6+1000;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
struct Point{
int x,y;
}Q[N];
int Sx[N];
int Sy[N];
int Px[N];
int Py[N];
int q;
int n;
signed main(){
// freopen("test.in","r",stdin);
int Cas;
read(Cas);
while(Cas--){
read(n);read(q);
for(int i=1;i<=n;++i){
int x,y;
read(x);
read(y);
Px[i]=x+y;
Py[i]=x-y;
}
for(int i=1;i<=q;++i){
int x,y;
read(x);
read(y);
Q[i].x=(x+y);
Q[i].y=(x-y);
}
sort(Px+1,Px+1+n);
sort(Py+1,Py+1+n);
for(int i=1;i<=n;++i){
Sx[i]=Sx[i-1]+Px[i];
Sy[i]=Sy[i-1]+Py[i];
}
for(int i=1;i<=q;++i){
int ans=0,pos;
pos=upper_bound(Px+1,Px+1+n,Q[i].x)-Px;
if(Px[1]<=Q[i].x){
ans+=(pos-1)*Q[i].x-Sx[pos-1];
}
if(Q[i].x<Px[n]){
ans+=Sx[n]-Sx[pos-1]-(n-pos+1)*Q[i].x;
}
pos=upper_bound(Py+1,Py+1+n,Q[i].y)-Py;
if(Py[1]<=Q[i].y){
ans+=(pos-1)*Q[i].y-Sy[pos-1];
}
if(Q[i].y<Py[n]){
ans+=Sy[n]-Sy[pos-1]-(n-pos+1)*Q[i].y;
}
cout<<ans/2<<'\n';
}
}
}