2022杭电多校3 Taxi个人补题

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(xxk+yyk,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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值