set维护凸包

Luogu 2521

set维护凸包外围周长!!

code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*t;
}
const double inf=1e9;
const int N=2e5+5;
struct node{
    int x,y;
    bool operator < (node a)const{return x<a.x;}
    bool operator == (node a)const{return a.x==x&&a.y==y;}
};
double K(node a,node b){return 1.0*(b.y-a.y)/(b.x-a.x);}
bool comp(node a,node b,node c){return K(a,b)<=K(b,c);}
double D(node a,node b){double xx=a.x-b.x,yy=a.y-b.y;return sqrt(xx*xx+yy*yy);}
set<node> st;
double sum;
void erase(set<node>::iterator it){
    // cout<<"erase"<<" "<<it->x<<" "<<it->y<<endl;
    set<node>::iterator i=next(it),j=prev(it);
    sum-=D(*j,*it);sum-=D(*it,*i);sum+=D(*j,*i);
    st.erase(it);
}
void ins(node a){
    set<node>::iterator it=st.lower_bound(a);
    if(it!=st.end()&&it->x==a.x){
        if(it->y<=a.y)erase(it);
        else return ;
    }
    while(true){
        set<node>::iterator i=st.lower_bound(a);
        if(i==st.begin())break;
        i--;if(i==st.begin())break;
        set<node>::iterator j=prev(i);
        if(comp(*j,*i,a))erase(i);
        else break;
    }
    while(true){
        set<node>::iterator i=st.lower_bound(a);
        if(i==st.end())break;
        set<node>::iterator j=next(i);
        if(j==st.end())break;
        // cout<<"BB"<<" "<<i->x<<" "<<i->y<<endl;
        if(comp(a,*i,*j))erase(i);
        else break;
    }
    it=st.lower_bound(a);
    if(it==st.begin()){sum+=D(a,*it);st.insert(a);}
    else if(it==st.end()){sum+=D(*prev(it),a);st.insert(a);}
    else {
        set<node>::iterator i=prev(it);
        if(!comp(*i,a,*it)){
            // cout<<"ZZ"<<a.x<<" "<<a.y<<" "<<i->x<<" "<<i->y<<" "<<it->x<<" "<<it->y<<endl;
            sum-=D(*i,*it);
            sum+=D(*i,a);sum+=D(a,*it);
            st.insert(a);
        }
    }
}
int n,m,qq;
struct Q{int tp,id;double ans;}q[N];
node a[N],sd,ll,rr;
bool vis[N];
signed main(){
    n=read();sd.x=read();sd.y=read();
    m=read();fo(i,1,m)a[i].x=read(),a[i].y=read();
    qq=read();fo(i,1,qq){
        q[i].tp=read();
        if(q[i].tp==1)q[i].id=read(),vis[q[i].id]=true;
    }
    ll=node{0,0};st.insert(node{-1,0});
    rr=node{n,0};st.insert(node{n+1,0});
    sum+=n+2;ins(sd);
    fo(i,1,m)if(!vis[i])ins(a[i]);
    fu(i,qq,1){
        if(q[i].tp==1)ins(a[q[i].id]);
        else {
            q[i].ans=sum;
            // cout<<sum<<endl;
            set<node>::iterator it=++st.begin();
            q[i].ans-=D(*st.begin(),*it);
            q[i].ans+=D(ll,*it);
            it=--st.end();it--;
            q[i].ans-=D(*--st.end(),*it);
            q[i].ans+=D(*it,rr);
        }
    }
    fo(i,1,qq)if(q[i].tp==2)printf("%.2lf\n",q[i].ans);
}
posted @ 2022-01-09 15:19  fengwu2005  阅读(95)  评论(1编辑  收藏  举报