• BZOJ 3533 向量集(凸包 + 二分 + 线段树)


    题目:传送门

    题意

     1 < =N < =4*10^5

    思路

    思路参考 ->

    代码参考->

    #include <bits/stdc++.h>
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define pb push_back
    using namespace std;
    
    typedef long long LL;
    const LL inf = 0x3f3f3f3f3f3f3f3fLL;
    const int N = 400050;
    
    struct Point {
        LL x, y;
        Point() { }
        Point(LL x = 0, LL y = 0) : x(x), y(y) { }
        LL operator * (const Point&a)const{return x*a.x+y*a.y;}
        LL operator ^ (const Point&a)const{return y*a.x-x*a.y;}
        Point operator + (const Point&a)const{return Point(x+a.x,y+a.y);}
        Point operator - (const Point&a)const{return Point(x-a.x,y-a.y);}
        bool operator < (const Point&a)const{return x==a.x?y<a.y:x<a.x;}
    };
    
    LL ans;
    char s[5], ch[5];
    int n, tot, x, y, l, r;
    vector < Point > tmp[N << 2], up[N << 2], dw[N << 2];
    
    void add(int rt, int l, int r, LL x, LL y, int pos) {
        tmp[rt].pb(Point(x, y));
        if(pos == r) {
            sort(tmp[rt].begin(), tmp[rt].end());
            for(int i = 0; i < tmp[rt].size(); i++) {
                while(up[rt].size() > 1 && ((up[rt][up[rt].size() - 1] - up[rt][up[rt].size() - 2]) ^ (tmp[rt][i] - up[rt][up[rt].size() - 1])) <= 0)
                    up[rt].pop_back();
                up[rt].pb(tmp[rt][i]);
    
                while(dw[rt].size() > 1 && ((dw[rt][dw[rt].size() - 1] - dw[rt][dw[rt].size() - 2]) ^ (tmp[rt][i] - dw[rt][dw[rt].size() - 1])) >= 0)
                    dw[rt].pop_back();
                dw[rt].pb(tmp[rt][i]);
            }
        }
    
        if(l == r) return ;
    
        int mid = (l + r) >> 1;
        if(pos <= mid) add(rt << 1, l, mid, x, y, pos);
        else add(rt << 1 | 1, mid + 1, r, x, y, pos);
    }
    
    void query(int rt, int l, int r, int L, int R, Point t) {
        if(L <= l && r <= R) {
            if(t.y >= 0) {
                int nowl = 1, nowr = up[rt].size() - 1, pos = 0;
                while(nowl <= nowr) {
                    int mid = (nowl + nowr) >> 1;
                    if(t * up[rt][mid] > t * up[rt][mid - 1]) {
                        pos = mid; nowl = mid + 1;
                    }
                    else nowr = mid - 1;
                }
                ans = max(ans, t * up[rt][pos]);
            }
            else {
                int nowl = 1, nowr = dw[rt].size() - 1, pos = 0;
                while(nowl <= nowr) {
                    int mid = (nowl + nowr) >> 1;
                    if(t * dw[rt][mid] > t * dw[rt][mid - 1]) {
                        pos = mid; nowl = mid + 1;
                    }
                    else nowr = mid - 1;
                }
                ans = max(ans, t * dw[rt][pos]);
            }
            return ;
        }
        int mid = (l + r) >> 1;
        if(L <= mid) query(rt << 1, l, mid, L, R, t);
        if(R > mid) query(rt << 1 | 1, mid + 1, r, L, R, t);
    }
    
    
    int main() {
        scanf("%d %s", &n, s);
    
        for(int i = 1; i <= n; i++) {
            scanf("%s %d %d", ch, &x, &y);
            if(s[0] != 'E') x ^= ans, y ^= ans;
            if(ch[0] == 'A') {
                tot++;
                add(1, 1, n, x, y, tot);
            }
            else {
                scanf("%d %d", &l, &r);
                if(s[0] != 'E') l ^= ans, r ^= ans;
                ans = -inf;
                query(1, 1, n, l, r, Point(x, y));
                printf("%lld
    ", ans);
                ans &= 0x7fffffff;
            }
        }
        return 0;
    }
    一步一步,永不停息
  • 相关阅读:
    Shell编程-02-Shell变量
    Linux 下强大的查找命令find
    DevOps 学院
    史上最详细、最全面的Hadoop环境搭建
    Linux 中10个命令链接操作符,帮助新手快速入门运维!
    25个Linux性能监控工具
    一文详解 Linux系统常用监控工具
    ansible 安装指南
    Tomcat管理页面
    Tomcat基础知识
  • 原文地址:https://www.cnblogs.com/Willems/p/12570862.html
Copyright © 2020-2023  润新知