动态维护凸包
来源:互联网 发布:手机维修网络培训 编辑:程序博客网 时间:2024/05/16 04:37
依次插入n个点,询问凸包面积。
利用granham思想,维护凸包,水平序要维护两个凸壳,比较麻烦,所以用极角序,每次查入用平衡树维护极角离他最近的点,此时到双向链表上开始模拟granham双向删点,直到无法删为止,因为每个点至多删一次,所以是nlogn的复杂度。面积维护用叉积即时维护即可。
依次插入n个半平面,询问半平面交面积。
与上题类似,维护法向量的极角,双向删半平面(当相邻一半平面两交点均在此半平面外即删),实现更复杂,我还没实现。
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>const int maxn=100005,oo=1073741819;struct point{ long long x,y; double t,d;}a[maxn],o;int n,rt[maxn],r[maxn],l[maxn],id[maxn],ins[maxn],net[maxn];long long sum,s[maxn],ans;void left(int x){ long long y=rt[x],z=rt[y]; r[y]=l[x],rt[l[x]]=y; l[x]=y,rt[y]=x; if (r[z]==y) r[z]=x;else l[z]=x;rt[x]=z;}void right(int x){ long long y=rt[x],z=rt[y]; l[y]=r[x],rt[r[x]]=y; r[x]=y,rt[y]=x; if (r[z]==y) r[z]=x;else l[z]=x;rt[x]=z;}int cmp(int x,int k){ if ((a[k].t>a[x].t)||((a[k].t==a[x].t)&&(a[k].d>a[x].d))) return -1; else if ((a[k].t<a[x].t)||((a[k].t==a[x].t)&&(a[k].d<a[x].d))) return 1; return 0;}long long cross(point e,point r){ return ((e.x*r.y)-(e.y*r.x));}long long cr(int i,int j,int k){ point e;e.x=a[j].x-a[i].x,e.y=a[j].y-a[i].y; point r;r.x=a[k].x-a[i].x,r.y=a[k].y-a[i].y; return cross(e,r);}long long dist(point e,point r){ long long x=e.x-r.x,y=e.y-r.y; return (x*x+y*y);}int ori(int k,int root){ id[k]=rand(),rt[k]=root;return k;}void inser(int k){ int x=0; for (;;) { if (cmp(x,k)==-1) if (r[x]!=0) x=r[x];else {r[x]=ori(k,x),x=r[x];break;} else if (cmp(x,k)==1) if (l[x]!=0) x=l[x];else {l[x]=ori(k,x),x=l[x];break;} else return ; } for (;id[rt[x]]>id[x];) if (l[rt[x]]==x) right(x);else left(x);}void cancel(int k){ net[ins[k]]=net[k],ins[net[k]]=ins[k]; sum=sum-s[ins[k]]-s[k]; s[ins[k]]=cross(a[ins[k]],a[net[k]]),sum=sum+s[ins[k]]; for (;(l[k])&&(r[k]);) if (id[l[k]]<id[r[k]]) right(l[k]);else left(r[k]); int j=(l[k]==0) ? r[k] : l[k]; if (l[rt[k]]==k) l[rt[k]]=j;else r[rt[k]]=j;rt[j]=rt[k];}int find(int k){ int ll=0,x=r[0],pd; for (;x;) { pd=cmp(x,k); if (pd==-1) ll=(cmp(ll,x)==-1) ? x : ll,x=r[x]; else if (pd==1) x=l[x]; else return x; } return ll;}void enter(int k){ a[k].t=atan2(a[k].y-o.y,a[k].x-o.x)*10000,a[k].d=dist(a[k],o); int i=find(k),j=net[i],flag=0; if (0==i) {for (;r[i]!=0;i=r[i]) ;j=net[i];} if (cmp(i,k)==0) return ; for (;(cr(ins[i],i,k)<=0);cancel(i),i=ins[i],flag=1) ; if ((1==flag)||(cr(i,k,j)>0)) { net[k]=net[i],ins[k]=i,ins[net[k]]=k,net[i]=k,inser(k); sum=sum-s[i],s[i]=cross(a[i],a[k]),s[k]=cross(a[k],a[j]); sum=sum+s[i]+s[k]; for (i=net[j];(cr(k,j,i)<=0);cancel(j),j=i,i=net[i]) ; }}void origin(){ int i,j; point c; id[0]=-oo,a[0].t=-oo; for (i=1;i<=3;i++) a[i].t=atan2(a[i].y-o.y,a[i].x-o.x)*10000,a[i].d=dist(a[i],o); for (i=1;i<=2;i++) for (j=i+1;j<=3;j++) if (cmp(i,j)==1) c=a[i],a[i]=a[j],a[j]=c; net[1]=2,net[2]=3,net[3]=1; ins[1]=3,ins[2]=1,ins[3]=2; s[1]=cross(a[1],a[2]),s[2]=cross(a[2],a[3]),s[3]=cross(a[3],a[1]); sum=s[1]+s[2]+s[3]; inser(1);inser(2);inser(3);}void init(){ int i,j,t,k; for (i=1;i<=3;o.x+=a[i].x,o.y+=a[i].y,i++) scanf("%d%d",&a[i].x,&a[i].y),a[i].x*=3,a[i].y*=3; o.x/=3,o.y/=3; origin(); sum=cross(a[1],a[2])+cross(a[2],a[3])+cross(a[3],a[1]); scanf("%d\n",&n); for (i=4;i<=n+3;i++) { scanf("%d%d",&a[i].x,&a[i].y),a[i].x*=3,a[i].y*=3; enter(i); if (sum<0) ans=-sum/9;else ans=sum/9; printf("%I64d\n",ans); }}int main(){ freopen("Convex.in","r",stdin); freopen("Convex.out","w",stdout); srand((int)time(NULL)); init(); return 0;}
- 动态维护凸包
- 代码备份:动态维护半平面交/凸包
- BZOJ 2300 HAOI 2011 防线修建 动态维护凸包
- BZOJ 2300 [HAOI2011]防线修建 Splay维护动态凸包
- [平衡树动态维护凸包] BZOJ 2300 [HAOI2011]防线修建
- [DP 斜率优化 CDQ分治||动态维护凸包] BZOJ 1492 [NOI2007]货币兑换Cash
- bzoj 2300: [HAOI2011]防线修建(splay动态维护凸包)
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
- pkgm : 动态压缩包维护与安装脚本
- 动态凸包
- 动态维护中位数
- 动态维护执行时机
- HDU 5033 Building 解题报告(维护凸包)
- BZOJ 2300 HAOI2011 防线修建 平衡树维护凸包
- 2300: [HAOI2011]防线修建 set维护凸包
- HDU 5033-B - Building-维护凸包-单调栈
- HDU 5033 Building (单调栈维护凸包)
- bzoj 4515 [Sdoi2016]游戏 线段树维护凸包
- ZOJ Problem Set - 1093 Monkey and Banana
- 【C++ Design Pattern-Creational】Factory Method(工厂方法)
- 新年上班第一天
- Ubuntu趣味应用探索----我们怎么在ubuntu上玩QQ
- ubuntu下设置samba服务
- 动态维护凸包
- Extjs3.0中的TreeGrid(Ext.ux.maximgb.tg.EditorGridPanel)
- 清狗电路分析
- 昊学昊思系列(一)——猫吃老鼠篇
- 如何去掉文件夹中.svn目录
- 第四天
- 欧拉函数应用
- S3C2440A中断小记
- Java防止SQL注入