zoukankan      html  css  js  c++  java
  • 「BZOJ2300」[HAOI2011] 防线修建

    传送门

    操作离线之后倒着做,只有加点操作。

    用set动态维护凸包即可。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<set>
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    const int N=100007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,m,q,cnt,no[N],qs[N][2],top;
    db ans,res[N];
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct pt {
        int x,y;
        pt(){}
        pt(int x,int y):x(x),y(y){}
        friend bool operator <(const pt&A,const pt&B) {
            return A.x<B.x||(A.x==B.x&&A.y<B.y);
        }
    }p[N],a[N],h[N];
    set<pt>s;
    
    pt operator - (const pt&A,const pt&B) { return pt(A.x-B.x,A.y-B.y); } 
    
    int cross(pt A,pt B) { return A.x*B.y-A.y*B.x; }
    LL dot(pt A,pt B) { return (LL)A.x*B.x+A.y*B.y; }
    db length(pt A) { return sqrt(dot(A,A)); }
    
    void make_ham(int n) {
        sort(a+2,a+n+1);
        h[++top]=a[1]; h[++top]=a[2];
        For(i,3,n) {
            while(top>1&&cross(h[top]-h[top-1],a[i]-h[top-1])>=0) top--;
            h[++top]=a[i]; 
        }
        For(i,1,top) {
            s.insert(h[i]);
            if(i>1) ans+=length(h[i]-h[i-1]);
        } 
    }
    
    #define IT set<pt>::iterator
    void insert(int id) {
        pt x=p[id];
        IT l=s.lower_bound(x);
        IT r=l,t; --l;
        if(cross(x-*l,*r-*l)>=0) return;
        ans-=length(*l-*r);
        while(1) {
            t=r; r++; if(r==s.end()) break;
            if(cross(*t-x,*r-x)>=0) {
                ans-=length(*t-*r); s.erase(t);
            }
            else break;
        }
        while(1) {
            if(l==s.begin()) break;
            t=l; l--;
            if(cross(*t-*l,x-*l)>=0) {
                 ans-=length(*t-*l); s.erase(t); 
            }
            else break;
        }    
        s.insert(x);  
        l=r=s.find(x); 
        --l; ++r;
        ans+=length(*l-x)+length(*r-x);
    }
    
    #define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("2300.in","r",stdin);
        freopen("2300.out","w",stdout);
    #endif
        read(n); read(p[0].x); read(p[0].y);
        read(m);
        For(i,1,m) { read(p[i].x); read(p[i].y); }
        read(q);
        For(i,1,q) {
            read(qs[i][0]);
            if(qs[i][0]==1) {
                read(qs[i][1]);
                no[qs[i][1]]=1;
            }
        }
        a[++cnt]=pt(0,0); a[++cnt]=pt(n,0);
        For(i,0,m) if(!no[i]) a[++cnt]=p[i];
        make_ham(cnt);
        Rep(i,q,1) {
            int o=qs[i][0],x=qs[i][1];
            if(o==2) res[i]=ans;
            else insert(x);
        }
        For(i,1,q) if(qs[i][0]==2) printf("%.2lf
    ",res[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    初级程序员面试不靠谱指南(三)
    [细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;
    20110310日记wmh
    SliverLight 控件属性的赋值方式
    20110309wmh日记
    20110308wmh日记
    20110307wmh日记
    STOAdiary20110314完成的任务
    20110313wmh日记
    20110311wmh日记
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8651450.html
Copyright © 2011-2022 走看看