zoukankan      html  css  js  c++  java
  • BZOJ 2300 防线修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=2300

    题意:给点,有以下操作:删去一个点,询问这些点构成凸包的周长。

    思路:用splay维护上凸壳,splay排序的关键字是X,同时还要记录每个点与左右点的斜率,当加入一个点时,我们找到它应该在的X的位置,一个个减掉左边,一个个减掉右边,符合条件就是当左边的斜率大于右边的斜率,就表明它在凸包上。

    PS:如果当前加入点的左边斜率小于右边斜率,说明它在凸包内,可以直接删掉这个点。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    struct node{
         int id,val,opt;
    }q[200005];
    struct point{
        double x,y;
    }p[200005];
    const double eps=1e-9;
    int tmp,root;
    double c[200005],xx[200005],yy[200005],ans,rk[200005],lk[200005];
    int n,ch[200005][2],fa[200005],vis[200005];
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    void rotate(int x,int &rt){
         int y=fa[x],z=fa[y],l,r;
         if (ch[y][0]==x) l=0;else l=1;r=l^1;
         if (y!=rt){
            if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
         }else rt=x;
         fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
         ch[y][l]=ch[x][r];ch[x][r]=y;
    }
    void splay(int x,int &rt){
         while (x!=rt){
            int y=fa[x],z=fa[y];
            if (y!=rt){
               if (ch[z][0]==y^ch[y][0]==x) rotate(x,rt);
               else rotate(y,rt);
            }
            rotate(x,rt);
         }
    }
    void find(int k,double X){
        if (!k) return;
        if (xx[k]<X+eps) tmp=k,find(ch[k][1],X);
        else find(ch[k][0],X);
    }    
    int suc(int x){
        x=ch[x][1];
        while (ch[x][0]) x=ch[x][0];
        return x;
    }
    int pre(int x){
        x=ch[x][0];
        while (ch[x][1]) x=ch[x][1];
        return x;
    }
    double sqr(double x){
        return x*x;
    }
    double dis(int x,int y){
        if (!x||!y) return 0.0;
        return sqrt(sqr(xx[x]-xx[y])+sqr(yy[x]-yy[y]));
    }
    void getslope(int x,int y){
        if (!x){lk[y]=1e9;return;}
        if (!y){rk[x]=-1e9;return;}
        if (fabs(xx[x]-xx[y])<1e-9){
            if (yy[x]<yy[y]) rk[x]=lk[y]=1e9;
            else rk[x]=lk[y]=-1e9;
            return;
        }
        rk[x]=lk[y]=(yy[x]-yy[y])/(xx[x]-xx[y]);
    }
    void insert(double X,double Y,int id){
        tmp=0;
        find(root,X);int x=tmp,y=0;
        if (!x){
           x=root;
           while (ch[x][0]) x=ch[x][0];
           splay(x,root);
           y=x;x=0;
        }else splay(x,root),splay(y=suc(x),ch[x][1]);
        xx[id]=X;yy[id]=Y;
        if (y) fa[id]=y,ch[y][0]=id;
        else fa[id]=x,ch[x][1]=id;
        getslope(x,id);getslope(id,y);
        ans-=dis(x,y);
        if (rk[id]>=lk[id]){getslope(x,y);fa[id]=0;ch[y][0]=0;ans+=dis(x,y);return;}
        splay(id,root);
        root=id;
        x=pre(id);
        ans+=dis(x,id);
        while (lk[x]<=rk[x]&&x){
            y=pre(x);
            splay(y,ch[x][0]);
            ans-=dis(x,id);
            ans-=dis(x,y);
            ans+=dis(y,id);
            fa[x]=ch[x][0]=ch[x][1]=0;
            ch[id][0]=y;fa[y]=id;
            getslope(y,id);
            x=y;
        }
        x=suc(id);
        ans+=dis(x,id);
        while (lk[x]<=rk[x]&&x){
           y=suc(x);
           splay(y,ch[x][1]);
           ans-=dis(x,id);
           ans-=dis(x,y);
           ans+=dis(y,id);
           fa[x]=ch[x][1]=ch[x][0]=0;
           ch[id][1]=y;fa[y]=id;
           getslope(id,y);
           x=y;
        }
    }
    int main(){
        int m=read(),x=read(),y=read();
        n=read();
        for (int i=1;i<=n;i++)
          scanf("%lf%lf",&p[i].x,&p[i].y);
        int T=read();
        for (int i=1;i<=T;i++){
          q[i].opt=read();
          if (q[i].opt==2) continue;
          q[i].id=i;q[i].val=read();vis[q[i].val]=1;
        }    
        insert(0,0,1);
        insert(m,0,2);
        insert(x,y,3);
        for (int i=1;i<=n;i++)
            if (!vis[i]){
                  insert(p[i].x,p[i].y,i+3);
            }
        int top=0;    
        for (int i=T;i>=1;i--){
            if (q[i].opt==2){
                c[++top]=ans;
            }else{
                insert(p[q[i].val].x,p[q[i].val].y,q[i].val+3);
            }
        }
        for (int i=top;i>=1;i--)
            printf("%.2f
    ",c[i]);
    }
  • 相关阅读:
    Nginx安装及配置
    nginx主(子)配置文件参考
    harbor私有仓库部署
    k8s内网安装部署(二)
    k8s部署之系统初始化(一)
    redis部署安装【建议收藏】
    nginx优化【收藏篇】
    nginx之用户验证配置(实操)
    nginx反向代理和负载均衡《实战》
    nginx安装
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5671055.html
Copyright © 2011-2022 走看看