题解 P2521 [HAOI2011]防线修建

Solution

实际上不需要使用set或平衡树来维护凸包 , 使用链表即可 .
我们记录每个点在整张图上的前点和后点和在凸包上的前点和后点 , 对于删除操作我们在链表上删除这个点 , 如果它在凸包上 , 那么重构它在凸包上的前后之间的区域并动态维护凸包周长 .

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
    int ret=0;char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')ret=(ret<<3)+(ret<<1)+(c^48),c=getchar();
    return ret;
}
const int maxn=1e5+5;
int n,m;
struct point
{
    int x,y;int ord;
    const bool operator <(const point &a)const{if(x!=a.x)return x<a.x;return y<a.y;}
    const point operator -(const point &a)const{return point{x-a.x,y-a.y};}
    const int operator *(const point &a)const{return x*a.y-a.x*y;}
    friend double dis(point &a,point &b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
}p[maxn];
int pre[maxn],nxt[maxn];
int cpre[maxn],cnxt[maxn];
bool used[maxn];
int sta[maxn],top;
double ans;
int num[maxn];
void andrew(int l,int r)
{
    top=0;sta[++top]=l;
    for(int i=nxt[l];i<=r;i=nxt[i])
    {
        while(top>=2&&(p[sta[top]]-p[sta[top-1]])*(p[i]-p[sta[top]])>=0)used[sta[top--]]=0;
        used[i]=1;
        sta[++top]=i;
    }
    for(int i=1;i<top;i++)ans+=dis(p[sta[i]],p[sta[i+1]]);
    for(int i=1;i<=top;i++)
    {
        if(i!=1)cpre[sta[i]]=sta[i-1];
        if(i!=top)cnxt[sta[i]]=sta[i+1];
    }
}
int main()
{
    p[2].x=read();p[3].x=read();p[3].y=read();
    n=read()+3;
    for(int i=4;i<=n;i++)p[i].x=read(),p[i].y=read(),p[i].ord=i-3;
    sort(p+1,p+n+1);
    for(int i=1;i<=n;i++)num[p[i].ord]=i;
    for(int i=1;i<=n;i++)pre[i]=i-1,nxt[i]=i+1;
    andrew(1,n);
    m=read();
    while(m--)
    {
        int opt=read();
        if(opt==1)
        {
            int x=read();
            x=num[x];
            pre[nxt[x]]=pre[x];
            nxt[pre[x]]=nxt[x];
            if(!used[x])continue;
            ans-=dis(p[cpre[x]],p[x])+dis(p[cnxt[x]],p[x]);
            andrew(cpre[x],cnxt[x]);
        }
        else if(opt==2)printf("%.2lf\n",ans);
    }
    return 0;
}
posted @ 2021-06-20 19:36  zero4338  阅读(35)  评论(0编辑  收藏  举报