1.个人反思
Orz
明显感觉自己太菜了,比赛化身隐形人 (悲
2.Taxi
给了n个点,m次查询,每次给一个坐标,求一个函数
即
f
(
x
)
=
{
M
a
x
(
M
i
n
(
∣
x
′
−
x
k
∣
+
∣
y
′
−
y
k
∣
,
w
k
)
)
,
k
∈
[
1
,
n
]
f(x)=\begin{cases} Max( Min(|x^′−x_k|+|y^′−y_k|,w_k) ) , & k∈[1,n]\\ \end{cases}
f(x)={Max(Min(∣x′−xk∣+∣y′−yk∣,wk)),k∈[1,n]
开始想法就是按照w排序,因为每一点在f(x)中是≤wk的,所以可以拿W作为二分的一个下界
然后就是这样的绝对值,很明显想到切比雪夫距离
切比雪夫距离(Chebyshev distance)是向量空间中的一种度量,二个点之间的距离定义为其各坐标数值差的最大值
是曼哈顿距离,将其拆开分解即可,之前写题时记错了,有题目是将曼哈顿距离和切比雪夫距离转换有类似的拆法
推倒这里后其实与答案十分接近了,而当时我写到这已经花了1个半小时,觉得误入歧途去看别的题了
二分的上界就是用上式进行约束,求出来的D是可能的最大值,如果当前mid点的W还要大于等于D,那么后面的点 k~n的函数值都不可能高于D了,故拿D进行更新
当前mid的W小于D就显然 1~k是无意义的,而后面的
W
i
W_i
Wi≥
W
m
i
d
W_{mid}
Wmid,
D
D
D≥
W
m
i
d
W_{mid}
Wmid,故答案可以拿
W
m
i
d
W_{mid}
Wmid更新
感觉很可惜,原因也是自己很菜,其实离答案很近了,但是没能继续写,而且推理也很慢,1个半小时才想起切比雪夫距离
wyy KDtree秒了,不会KDtree,看不懂
#include<bits/stdc++.h>
usingnamespace std;
typedef pair<int,int> pr;
constint inf =0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define in freopen("in.txt","r",stdin)
#define out freopen("out.txt","w",stdout)
#define ms(x,a) memset(x,a,sizeof(x))
#define ll long long
#define pb push_back
#define pr pair<int,int>
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define rg register int
#define ONLINE_JUDGE
constint mod=1e9+7;
constint maxn=1e5+10;
constint maxe=1e6+5;
int n,m,k;
struct node{
ll x,y,w;
};
bool cmp(const node &a, const node &b){
return a.w < b.w;
}
void solve()
{
scanf("%d %d",&n,&m);
vector<node> a;
vector<ll> weight;
ll x,y,w;
for(int i=1;i<=n;i++){
scanf("%lld %lld %lld",&x,&y,&w);
a.pb({x,y,w});
}
sort(a.begin(),a.end(),cmp);
vector<ll> CBdis[5];
CBdis[1].resize(n+1);CBdis[2].resize(n+1);CBdis[3].resize(n+1);CBdis[4].resize(n+1);
CBdis[1][n-1]=max(-1ll*inf,-a[n-1].x-a[n-1].y);
CBdis[2][n-1]=max(-1ll*inf,-a[n-1].x+a[n-1].y);
CBdis[3][n-1]=max(-1ll*inf,a[n-1].x-a[n-1].y);
CBdis[4][n-1]=max(-1ll*inf,a[n-1].x+a[n-1].y);
for(int i=n-2;i>=0;i--){
CBdis[1][i]=max(CBdis[1][i+1],-a[i].x-a[i].y);
CBdis[2][i]=max(CBdis[2][i+1],-a[i].x+a[i].y);
CBdis[3][i]=max(CBdis[3][i+1],a[i].x-a[i].y);
CBdis[4][i]=max(CBdis[4][i+1],a[i].x+a[i].y);
}
for(int i=0;i<n;i++){
weight.pb(a[i].w);
}
for(int i=1;i<=m;i++){
scanf("%lld %lld",&x,&y);
int l=0,r=n-1,mid;
ll ans=0;
while(l<=r){
mid=(l+r)>>1;
ll dis=max(max(x+y+CBdis[1][mid],x-y+CBdis[2][mid]),max(-x+y+CBdis[3][mid],-x-y+CBdis[4][mid]));
//dis是到后续所有点的最大可能距离
if(weight[mid]>=dis){//w等于是当前点的上限,而后续所有点的最大值是小于当前点
//的,故剩下的可能性在前面
r=mid-1;
ans=max(ans,dis);
}else{//1-mid的所有点的上限都小于后面的最大距离,则1-k不用考虑了
l=mid+1;
ans=max(ans,weight[mid]);
}
}
printf("%lld\n",ans);
}
return ;
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return0;
}