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; }