zoukankan      html  css  js  c++  java
  • BZOJ 2300 [HAOI2011]防线修建 ——计算几何

    只需要倒着插入,然后维护一个凸包就可以了。

    可以用来学习set的用法

    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define inf 100000
    #define ll long long
    #define mp make_pair
    #define sqr(x) x*x
     
    int n,x,y,m,k;
    struct Vector{
        double x,y;
        void print(){printf("Vector (%.3f,%.3f)
    ",x,y);}
    };
     
    struct Point{
        int x,y;
        void print(){printf("Point (%d,%d)
    ",x,y);}
        bool operator < (const Point b) const{
            return x==b.x?y<b.y:x<b.x;
        }
    }a[200005];
     
    set <Point> s;
     
    struct Options{int opt,id;}q[200005];
     
    double dist (Point a,Point b)
    {
    //  printf("dist
    ");
    //  a.print();b.print();
    //  printf("The ans is %.6f
    ",sqr((double)a.x-b.x)+sqr((double)a.y-b.y));
        return sqrt(((double)a.x-b.x)*((double)a.x-b.x)+((double)a.y-b.y)*((double)a.y-b.y));
    }
     
    Vector operator - (Point a,Point b)
    {Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;}
     
    double operator * (Vector a,Vector b)
    {
    //  a.print(); printf("* * *
    ");
    //  b.print();
    //  printf("= %.6f
    ",a.x*b.y-a.y*b.x);
        return a.x*b.y-a.y*b.x;
    }
     
    int tot,del[200005];
    double ans[200005],now;
    Point newnode;
     
    void init()
    {
        now=n*1.0;
        newnode.x=0;newnode.y=0;
        s.insert(newnode);
    //  newnode.x=0;newnode.y=-inf;
    //  s.insert(newnode);
        newnode.x=n;newnode.y=0;
        s.insert(newnode);
    //  newnode.x=n;newnode.y=-inf;
    //  s.insert(newnode);
    //  printf("now is %.6f
    ",now);
    }
     
    void add(Point x)
    {
    //  printf("Add "); x.print();
        set<Point>::iterator it,iL,iR;
        it=s.lower_bound(x);
        iL=it;iL--;iR=it;
        if ((x-*iL)*(*iR-x)>0) return;
    //  printf("New node
    ");
        now-=dist(*iL,*iR);
        for (;;)
        {
            iR=it;it++;
            if (it==s.end()) break;
            if ((*iR-x)*(*it-x)>0)
            {
                now-=dist(*iR,*it);
                s.erase(*iR);
    //          printf("del R
    "); while (1);
            }
            else break;
        }
        for (;;)
        {
            if (iL==s.begin()) break;
            Point L=*iL; iL--;
    //      (*iL-*it).print();
    //      (*it-x).print();
            if ((L-*iL)*(x-*iL)>0)
            {
                now-=dist(*iL,L);
                s.erase(L);
    //          printf("del L
    "); //while(1);
            }
            else break;
        }
        s.insert(x);
        it=s.find(x);
        iL=it;iL--;iR=it;iR++;
        now+=dist(*iL,x)+dist(x,*iR);
    //  printf("now is %.6f
    ",now);
        return ;
    }
     
    void Finout()
    {
        freopen("defense.in","r",stdin);
        freopen("defense.out","w",stdout);
    }
     
    int main()
    {
    //  freopen("in.txt","r",stdin);
        scanf("%d%d%d",&n,&x,&y);
        scanf("%d",&m);
        F(i,1,m) scanf("%d%d",&a[i].x,&a[i].y);
        scanf("%d",&k);
    //  printf("k is %d
    ",k);
        F(i,1,k)
        {
            scanf("%d",&q[i].opt);
            switch(q[i].opt)
            {
                case 1:scanf("%d",&q[i].id); del[q[i].id]=1;break;
                case 2:q[i].id=++tot; break;
            }
        }
    //  F(i,1,k) printf("Opt %d id %d
    ",q[i].opt,q[i].id);
        init(); newnode.x=x;newnode.y=y;add(newnode);
        F(i,1,m) if (!del[i]) add(a[i]);
        D(i,k,1)
        {
            switch(q[i].opt)
            {
                case 1:add(a[q[i].id]);break;
                case 2:ans[q[i].id]=now;break;
            }
        }
        F(i,1,tot) printf("%.2f
    ",ans[i]);
    }
    

      

  • 相关阅读:
    关于table表格的一些问题
    leetcode 845. 数组中的最长山脉 做题笔记
    leetcode 845. 数组中的最长山脉 做题小结
    leetcode 925. 长按键入小结
    leetcode 925. 长按键入小结
    java单链表反转 详细讲述
    java单链表反转 详细讲述
    Leetcode 3. 无重复字符的最长子串 做题小结
    Leetcode 3. 无重复字符的最长子串 做题小结
    复变函数的幂函数
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6686153.html
Copyright © 2011-2022 走看看