• bzoj 2300: [HAOI2011]防线修建 凸包


    题目大意:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2300

    题解

    这道题让我们维护一个支持动态删除点的上凸壳
    并且告诉了我们三个一定不会被删除的点
    也就是说,无论什么时候这都是一个凸包
    如果我们考虑从凸包里删除一个点吗...这个点在凸包里还好说,不用管了
    在凸包上嘛...哪位dalao写出来了请教教我,并不会删除QAQ
    所以我们倒序考虑所有的操作,将其变成动态插入点
    每一次插入一个点的时候,我们找到凸包上与这个点关联的两个点
    (按照横纵坐标进行双关键字排序后与之相邻的两个点)
    我们就从这两个点开始依次向左右拓展,并且即时更新凸包的长度
    所以我们用set存一下所有在凸包上的点即可

    #include <set>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 100010;
    const int maxm = 200010;
    struct Point{
        int x,y;
        Point(const int &a = 0,const int &b = 0){x=a;y=b;}
        void print(){
            printf("Point : (%d,%d)
    ",x,y);
        }
    };
    typedef Point Vector;
    Vector operator + (const Vector &a,const Vector &b){
        return Vector(a.x+b.x,a.y+b.y);
    }
    Vector operator - (const Vector &a,const Vector &b){
        return Vector(a.x-b.x,a.y-b.y);
    }
    bool operator < (const Point &a,const Point &b){
        return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    int operator * (const Vector &a,const Vector &b){
        return a.x*b.x + a.y*b.y;
    }
    inline int cross(const Vector &a,const Vector &b){
        return a.x*b.y - a.y*b.x;
    }
    inline double sqr(const double &x){
        return x*x;
    }
    inline double dis(Point a,Point b){
        return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
    }
    struct Node{
        int cmd,x;
    }quer[maxm];
    set<Point>s;
    Point p[maxn];bool vis[maxn];
    double ans = .0;
    double anss[maxm];int cnt;
    void insert(Point x){
        set<Point>::iterator r = s.lower_bound(x);
        set<Point>::iterator l = --r;r++;
        set<Point>::iterator it;
        if(cross(x - *l,*r - *l) >= 0) return;
        ans -= dis(*l,*r);
        while(1){
            it = r++;
            if(r == s.end()) break;
            if(cross(*r - *it,*it - x) > 0) break;
            ans -= dis(*it,*r);s.erase(it);
        }
        ans += dis(x,*it);
        while(1){
            it = l--;
            if(it == s.begin()) break;
            if(cross(x - *it,*it - *l) > 0) break;
            ans -= dis(*it,*l);s.erase(it);
        }
        ans += dis(x,*(it));
        s.insert(x);
    }
    int main(){
        int n,x,y;read(n);read(x);read(y);
        s.insert(Point(0,0));
        s.insert(Point(x,y));
        s.insert(Point(n,0));
        ans += dis(Point(0,0),Point(x,y)) + dis(Point(x,y),Point(n,0));
        read(n);
        for(int i=1;i<=n;++i){
            read(p[i].x);
            read(p[i].y);
        }
        int m;read(m);
        for(int i=1;i<=m;++i){
            read(quer[i].cmd);
            if(quer[i].cmd == 1){
                read(quer[i].x);
                vis[quer[i].x] = true;
            }
        }
        for(int i=1;i<=n;++i){
            if(!vis[i]) insert(p[i]);
        }
        for(int i=m;i>=1;--i){
            if(quer[i].cmd == 1) insert(p[quer[i].x]);
            else anss[++cnt] = ans;
        }
        for(int i=cnt;i>=1;--i) printf("%.2lf
    ",anss[i]);
        getchar();getchar();
        return 0;
    }
    
  • 相关阅读:
    如何解决C#异常:必须先将当前线程设置为单线程单元(STA)模式,然后才能进行OLE调用,请确保你的Main函数已在其上标记了STAThreadAttribute
    go多态
    go泛型
    protoc工具使用
    grpc protobuf协议
    grpc根据proto文件自动生成go源码
    go安装grpc
    go protobuf
    go读取http.Request中body的内容
    go数据库操作
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6435533.html
Copyright © 2020-2023  润新知