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
  • 相关阅读:
    jQuery EasyUI API 中文文档 数字框(NumberBox)
    jQuery EasyUI API 中文文档 数值微调器(NumberSpinner)
    jQuery EasyUI API 中文文档 日期时间框(DateTimeBox)
    jQuery EasyUI API 中文文档 微调器(Spinner)
    jQuery EasyUI API 中文文档 树表格(TreeGrid)
    jQuery EasyUI API 中文文档 树(Tree)
    jQuery EasyUI API 中文文档 属性表格(PropertyGrid)
    EntityFramework 数据操作
    jQuery EasyUI API 中文文档 对话框(Dialog)
    jQuery EasyUI API 中文文档 组合表格(ComboGrid)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8651450.html
Copyright © 2011-2022 走看看