bzoj 2300: [HAOI2011]防线修建
(提前声明,,,代码丑陋之极。。。。)
一眼看到这个题,,好神哇,,不会做。。
然后发现可以翻过来,离线处理,把删点改成加点会比较简单,这样就办成了一个动态加点维护上凸壳了呀!!!我的天呢!!!(这不是神犇拿来装逼的东西??)
因为我太虚把,所以先搞出来了最后的凸壳什么样子。
然后想,上凸壳这么神的东西,加进去会导致原来的点无效,就要删除,还要支持插入点,而且要有序,,一想可以用set维护一下啊,然后对于要往里面加的点,要先判断是不是在凸壳里面,不是的话,加上这个点,在往两边暴力修改,(就是判断是不是满足凸壳就好),思路就是这么简单。。
(代码能力真的是个蛋疼的东西。。。。整整调了半天。。)
(把最后凸壳插入set的时候写错数组,一开始把向两边修改的代码写的奇蠢无比,快7,80行,里面的迭代器不知道it--和--it是不是和数一样用,然后就乱写,各种各样sb错误。。。诶,,,实在虚。。)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<map> 6 #include<iostream> 7 #include<set> 8 #define N 100005 9 #define eps 1e-8 10 using namespace std; 11 int n,m,Q,cnt,top,num; 12 bool vis[N]; 13 double x,y,ans,ans1[N<<1]; 14 struct point{double x,y;}pre[N],p[N],st[N],del[N]; 15 struct query{int opt,pos;}q[N<<1]; 16 set<point > s; 17 set<point > :: iterator it1,it2,it,old; 18 bool operator < (point a, point b) 19 { 20 return a.x<b.x; 21 } 22 inline double dis(point a, point b) 23 { 24 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 25 } 26 inline double cross(point p1, point p2, point p0) 27 { 28 return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); 29 } 30 inline bool cmp(point a, point b) 31 { 32 if (cross(a,b,pre[0])==0) return dis(a,pre[0])<dis(b,pre[0]); 33 return cross(a,b,pre[0])>0; 34 } 35 void Graham() 36 { 37 pre[2].x=n; pre[2].y=0.0; 38 pre[1].x=x; pre[1].y=y; 39 pre[0].x=0.0; pre[0].y=0.0; 40 cnt=2; 41 for (int i=1; i<=m; i++) 42 if (!vis[i]) pre[++cnt]=p[i]; 43 // for (int i=1; i<=cnt; i++) 44 // cout<<pre[i].x<<" "<<pre[i].y<<endl; cout<<endl; 45 top=2; 46 sort(pre+1,pre+cnt+1,cmp); 47 st[0]=pre[0],st[1]=pre[1],st[2]=pre[2]; 48 for (int i=3; i<=cnt; i++) 49 { 50 while (top && cross(pre[i],st[top],st[top-1])>=0) top--; 51 st[++top]=pre[i]; 52 } 53 for (int i=0; i<=top; i++) 54 s.insert(st[i]); //sbsbsbsbbsb...insert(pre[..])heheheheh,,,f**k??!! 55 st[++top]=pre[0]; 56 for (int i=0; i<top; i++) 57 ans+=dis(st[i],st[i+1]); 58 ans-=n; 59 // printf("%lf",ans); while (1); 60 } 61 void rebuild(int i) 62 { 63 //for (it=s.begin(); it!=s.end(); it++) 64 // printf("%lf %lf\n",(*it).x,(*it).y); system("pause"); 65 point new_in=p[i]; num=0; 66 it=s.lower_bound(new_in); old=it; 67 point a=*it; it--; point b=*it; 68 // printf("%lf %lf\n",a.x,a.y); 69 // printf("%lf",new_in.y-a.y-(b.y-a.y)/(a.x-b.x)*(a.x-new_in.x));system("pause"); 70 if (new_in.y-a.y-(b.y-a.y)/(a.x-b.x)*(a.x-new_in.x)>eps) 71 { 72 ans-=dis(a,b); 73 ans+=dis(new_in,a); ans+=dis(new_in,b); 74 } 75 else return; 76 it1=it; it--; it2=it; 77 for (;it1!=s.begin(); it2--,it1--) 78 { 79 point c=*it1,d=*it2; 80 if (cross(d,c,new_in)>0) 81 { 82 ans-=dis(new_in,c); 83 ans-=dis(c,d); 84 ans+=dis(new_in,d); 85 del[++num]=c; 86 } 87 } 88 it=old; it1=it; it++; it2=it; 89 for (; it2!=s.end(); it1++,it2++) 90 { 91 point c=*it1,d=*it2; 92 if (cross(c,d,new_in)>0) 93 { 94 ans-=dis(new_in,c); 95 ans-=dis(c,d); 96 ans+=dis(new_in,d); 97 del[++num]=c; 98 } 99 else break; 100 } 101 for (int j=1; j<=num; j++) 102 { 103 // if (del[j].x==x && del[j].y==y) continue; 104 s.erase(s.find(del[j])); 105 } 106 s.insert(new_in); 107 } 108 int main() 109 { 110 scanf("%d%lf%lf%d",&n,&x,&y,&m); 111 for (int i=1; i<=m; i++) 112 scanf("%lf%lf",&p[i].x,&p[i].y); 113 scanf("%d",&Q); 114 for (int i=1; i<=Q; i++) 115 { 116 scanf("%d",&q[i].opt); 117 if (q[i].opt==1) 118 { 119 scanf("%d",&q[i].pos); 120 vis[q[i].pos]=1; 121 } 122 } 123 Graham(); int tot=0; 124 for (int i=Q; i>=1; i--) 125 { 126 if (q[i].opt==2) ans1[++tot]=ans; 127 else rebuild(q[i].pos); 128 } 129 for (int i=tot; i>=1; i--) 130 printf("%.2lf\n",ans1[i]); 131 return 0; 132 }