• 【补题日记】[2022杭电暑期多校3]K-Taxi


    Pro

    https://acm.hdu.edu.cn/showproblem.php?pid=7172

    Sol

    先考虑没有w的限制的我不会的经典模型怎么做。

    ∵ ∣ x ∣ = m a x ( x , − x ) \because |x|=max(x,-x) x=max(x,x)
    ∴ m a x ( ∣ x ′ − x i ∣ + ∣ y ′ − y i ∣ ) \therefore max({|x^{'}-x_i|+|y^{'}-y_i|}) max(xxi+yyi)
    = m a x { m a x ( x ′ − x i , − x ′ + x i ) + m a x ( y ′ − y i , − y ′ + y i ) } =max\{max(x^{'}-x_i, -x^{'}+x_i)+ {max(y^{'}-y_i, -y^{'}+y_i)}\} =max{max(xxi,x+xi)+max(yyi,y+yi)}
    = m a x { x ′ − x i + y ′ − y i , x ′ − x i − y ′ + y i , − x ′ + x i + y ′ − y i , − x ′ + x i − y ′ + y i } =max\{x^{'}-x_i+y^{'}-y_i, x^{'}-x_i-y^{'}+y_i, -x^{'}+x_i+y^{'}-y_i,-x^{'}+x_i-y^{'}+y_i \} =max{xxi+yyi,xxiy+yi,x+xi+yyi,x+xiy+yi}
    = m a x { ( x ′ + y ′ ) + ( − x i − y i ) , ( x ′ − y ′ ) + ( − x i + y i ) , ( − x ′ + y ′ ) + ( x i − y i ) , ( − x ′ − y ′ ) + ( x i + y i ) } =max\{(x^{'}+y^{'})+(-x_i-y_i), (x^{'}-y^{'})+(-x_i+y_i), (-x^{'}+y^{'})+(x_i-y_i),(-x^{'}-y^{'})+(x_i+y_i) \} =max{(x+y)+(xiyi),(xy)+(xi+yi),(x+y)+(xiyi),(xy)+(xi+yi)}
    因此只需要维护 − x i − y i , − x i + y i , x i − y i , x i + y i -x_i-y_i,-x_i+y_i,x_i-y_i,x_i+y_i xiyi,xi+yi,xiyi,xi+yi就可以 O ( 1 ) O(1) O(1)的时间求出距离该点的曼哈顿距离最大值。

    而本题加入w的限制后,有以下两种二分思路来做:(经过测试,第一种虽做法虽然只比第二种多了个log,但是因为此处的n比较大,因此不能通过;第二种方法关掉流同步的cin和快读也不能A掉,只能scanf才A掉哈哈哈,归为hdu机子的问题上次1e5的O(n)都给我T了我还记着呢

    主要是check(judge)函数的区别

    1、直接二分答案,比如想要判断答案是不是大于等于x,那么找到第一个权值大于等于x的点,根据上面的式子求出原始模型的距离,然后与x比较即可。

    因为外面有一层二分,里面可以使用lower_bound二分得到点的下标,因此总的时间复杂度 O ( n l o g n l o g n ) O(nlognlogn) O(nlognlogn)

    2、二分城镇
    考虑判断第x个城镇,它的点权为a[x].w,求出编号大于等于x的城镇中到询问点的最大曼哈顿距离d

    如果d>a[x].w,答案一定大于等于a[x].w,因此需要进一步二分右半区间;反之同理。总的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

    Code

    1.二分答案

    //By cls1277
    #include
    using namespace std;
    typedef long long LL;
    #define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
    #define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
    #define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
    #define Ms(a,b) memset((a),(b),sizeof(a))
    #define endl '\n'
    
    const LL maxn = 1e5+5;
    LL n, q;
    struct Node {
        LL x, y, w;
    }a[maxn];
    LL b[maxn];
    
    inline LL read() {
    	LL x = 0, f = 1;char c = getchar();
    	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
    	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
    	return x * f;
    }
    
    LL f[4][maxn]; //0:x+y 1:x-y 2:-x+y 3:-x-y
    
    bool operator < (const Node&x, const Node&y) {
        return x.w<y.w;
    }
    
    bool judge(LL x, LL y, LL w) {
        LL idx = lower_bound(b+1, b+n+1, w)-b;
        LL d = max({x+y+f[3][idx], x-y+f[2][idx], -x+y+f[1][idx], -x-y+f[0][idx]});
        return (d>=w);
    }
    
    int main() {
        // ios::sync_with_stdio(false);
        // cin.tie(nullptr);
        #ifdef DEBUG
        freopen("data.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        LL t; scanf("%lld",&t); //t=read(); //cin>>t;
        while(t--) {
            scanf("%lld%lld",&n,&q);
            // n=read(); q=read(); //cin>>n>>q;
            Fo(i,1,n) {
                // a[i].x = read();
                // a[i].y = read();
                // a[i].w = read();
                scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].w);
            }
            //cin>>a[i].x>>a[i].y>>a[i].w;
            sort(a+1, a+n+1);
            Fo(i,1,n) {
                b[i] = a[i].w;
                f[0][i] = f[1][i] = f[2][i] = f[3][i] = 0;
            }
            f[0][n] = a[n].x+a[n].y;
            f[1][n] = a[n].x-a[n].y;
            f[2][n] = -a[n].x+a[n].y;
            f[3][n] = -a[n].x-a[n].y;
            Ro(i,n-1,1) {
                f[0][i] = max(f[0][i+1], a[i].x+a[i].y);
                f[1][i] = max(f[1][i+1], a[i].x-a[i].y);
                f[2][i] = max(f[2][i+1], -a[i].x+a[i].y);
                f[3][i] = max(f[3][i+1], -a[i].x-a[i].y);            
            }
            while(q--) {
                LL _x, _y; scanf("%lld%lld", &_x, &_y); // _x=read(); _y=read(); //cin>>_x>>_y;
                LL l=0, r=a[n].w;
                while(l<r) {
                    LL mid=(l+r+1)>>1;
                    if(judge(_x, _y, mid)) l = mid;
                    else r = mid-1;
                }
                // cout<
                printf("%lld\n",l);
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    2.二分城镇:

    //By cls1277
    #include
    using namespace std;
    typedef long long LL;
    #define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
    #define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
    #define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
    #define Ms(a,b) memset((a),(b),sizeof(a))
    #define endl '\n'
    
    const LL maxn = 1e5+5;
    LL n, q;
    struct Node {
        LL x, y, w;
    }a[maxn];
    LL b[maxn];
    
    inline LL read() {
    	LL x = 0, f = 1;char c = getchar();
    	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
    	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
    	return x * f;
    }
    
    LL f[4][maxn]; //0:x+y 1:x-y 2:-x+y 3:-x-y
    
    bool operator < (const Node&x, const Node&y) {
        return x.w<y.w;
    }
    
    LL ans = 0;
    
    bool judge(LL x, LL y, LL idx) {
        LL d = max({x+y+f[3][idx], x-y+f[2][idx], -x+y+f[1][idx], -x-y+f[0][idx]});
        if(d>=a[idx].w) {
            ans = max(ans, a[idx].w);
            return true;
        } else {
            ans = max(ans, d);
            return false;
        }
    }
    
    int main() {
        // ios::sync_with_stdio(false);
        // cin.tie(nullptr);
        #ifdef DEBUG
        freopen("data.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        LL t; scanf("%lld",&t); //t=read(); //cin>>t;
        while(t--) {
            scanf("%lld%lld",&n,&q);
            // n=read(); q=read(); //cin>>n>>q;
            Fo(i,1,n) {
                // a[i].x = read();
                // a[i].y = read();
                // a[i].w = read();
                scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].w);
            }
            //cin>>a[i].x>>a[i].y>>a[i].w;
            sort(a+1, a+n+1);
            Fo(i,1,n) {
                b[i] = a[i].w;
                f[0][i] = f[1][i] = f[2][i] = f[3][i] = 0;
            }
            f[0][n] = a[n].x+a[n].y;
            f[1][n] = a[n].x-a[n].y;
            f[2][n] = -a[n].x+a[n].y;
            f[3][n] = -a[n].x-a[n].y;
            Ro(i,n-1,1) {
                f[0][i] = max(f[0][i+1], a[i].x+a[i].y);
                f[1][i] = max(f[1][i+1], a[i].x-a[i].y);
                f[2][i] = max(f[2][i+1], -a[i].x+a[i].y);
                f[3][i] = max(f[3][i+1], -a[i].x-a[i].y);            
            }
            while(q--) {
                LL _x, _y; scanf("%lld%lld", &_x, &_y); // _x=read(); _y=read(); //cin>>_x>>_y;
                LL l=0, r=n;
                ans = 0;
                while(l<r) {
                    LL mid=(l+r+1)>>1;
                    if(judge(_x, _y, mid)) l = mid;
                    else r = mid-1;
                }
                // cout<
                printf("%lld\n",ans);
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
  • 相关阅读:
    MindFusion.Diagramming for JavaScript V4.2.3
    再见了青春,联想Y450最后一次升级,真的神一般存在。
    c++模板
    Deepstream 6.1.1 以及 Python Binding 安装过程记录
    docker内部无法使用ping等网络工具解决方案
    安卓系统怎样监听系统值的改变?
    浅析GC-垃圾回收
    Unity UI Toolkit学习笔记-Runtime UI 案例实践
    HWAutoTool 自动化工具操作手机模拟器文档介绍
    帆软学习记录
  • 原文地址:https://blog.csdn.net/cls1277/article/details/126168279