ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

给你N个点,请循环完成下列任务 1:求出这N个点的凸包的面积 2:拿掉最左或最右或最上或最下的一个点,当点的个数不足三个时停止

Input

第一行,一个数字N 接下来N行,每行两个数Xi,Yi 接下来,一个字符串,表示每次拿走的点(仅为UDLR代表上下左右)

Output

输出有N-2行,每行一个实数,保留一位小数

预处理删点顺序,逆序加点,用set和链表维护凸包上的点的极角序(以最初凸包内一点为原点),每次更新凸包时计算面积的变化量。

#include<bits/stdc++.h>
typedef long long i64;
int _(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
int n;
double xs=0,ys=0;
struct _pos{
    int id;
    double a;
    bool operator<(const _pos&w)const{return a<w.a;}
};
std::set<_pos>ss;
struct pos{
    int x,y,id;
    _pos get(){return(_pos){id,std::atan2(y-ys,x-xs)};}
}ps[300007],ps2[300007],ps0[300007];
bool cx(const pos&a,const pos&b){return a.x<b.x;}
bool cy(const pos&a,const pos&b){return a.y<b.y;}
char s[300007];
bool del[300007];
int ds[300007],dp=0,nx[300007],pv[300007],cs[4],ap=0;
i64 ans=0,as[300007];
bool chk(int a,int b,int c){
    return i64(ps0[a].x-ps0[b].x)*(ps0[c].y-ps0[b].y)-i64(ps0[c].x-ps0[b].x)*(ps0[a].y-ps0[b].y)>=0;
}
void cal(int a,int b,int c){
    ans+=i64(ps0[c].x-ps0[b].x)*(ps0[a].y-ps0[b].y)-i64(ps0[a].x-ps0[b].x)*(ps0[c].y-ps0[b].y);
}
void dels(int w){
    cal(nx[w],w,pv[w]);
    nx[pv[w]]=nx[w];
    pv[nx[w]]=pv[w];
    ss.erase(ss.find(ps0[w].get()));
}
void inss(int l,int a,int r,_pos w){
    cal(l,a,r);
    nx[pv[a]=l]=pv[nx[a]=r]=a;
    ss.insert(w);
}
int main(){
    n=_();
    for(int i=0;i<n;++i){
        ps[i].x=_();
        ps[i].y=_();
        ps[i].id=i;
    }
    memcpy(ps2,ps,sizeof(pos)*n);
    memcpy(ps0,ps,sizeof(pos)*n);
    std::sort(ps,ps+n,cx);
    std::sort(ps2,ps2+n,cy);
    int l1=0,r1=n-1,l2=0,r2=n-1;
    scanf("%s",s);
    for(int i=0;s[i];++i){
        if(s[i]=='L'){
            while(del[ps[l1].id])++l1;
            del[ds[dp++]=ps[l1++].id]=1;
        }else
        if(s[i]=='R'){
            while(del[ps[r1].id])--r1;
            del[ds[dp++]=ps[r1--].id]=1;
        }else
        if(s[i]=='D'){
            while(del[ps2[l2].id])++l2;
            del[ds[dp++]=ps2[l2++].id]=1;
        }else{
            while(del[ps2[r2].id])--r2;
            del[ds[dp++]=ps2[r2--].id]=1;
        }
    }
    int cp=0;
    for(int i=l1;i<=r1;++i)if(!del[ps[i].id]){
        xs+=ps[i].x;
        ys+=ps[i].y;
        cs[cp++]=ps[i].id;
    }
    xs/=2;ys/=2;
    ss.insert(ps0[cs[0]].get());
    ss.insert(ps0[cs[1]].get());
    pv[cs[0]]=nx[cs[0]]=cs[1];
    pv[cs[1]]=nx[cs[1]]=cs[0];
    while(dp){
        int a=ds[--dp];
        _pos w=ps0[a].get();
        std::set<_pos>::iterator it=ss.lower_bound(w);
        if(it==ss.end())it=ss.begin();
        int r=it->id,l=pv[r];
        if(!chk(l,a,r)){
            while(chk(a,r,nx[r]))dels(r),r=nx[r];
            while(chk(pv[l],l,a))dels(l),l=pv[l];
            inss(l,a,r,w);
        }
        as[ap++]=ans;
    }
    while(ap){
        ans=as[--ap];
        printf("%lld.%lld\n",ans>>1,5*(ans&1));
    }
    return 0;
}

 

posted on 2016-12-19 13:56  nul  阅读(349)  评论(0编辑  收藏  举报