zoukankan      html  css  js  c++  java
  • 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
    ",(*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
    ",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
    ",ans1[i]);
    131     return 0;
    132 }
  • 相关阅读:
    202002知识点
    爬取思想流程
    测试
    运维
    设计模式重温
    ?March2020疑问点
    最方便简洁的设置Sublime编辑预览MarkDown
    rime中州韵输入法安装及配置
    Deepin更新Sublime并取消更新提示
    关于在线教学软件一些发现和思考
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6480913.html
Copyright © 2011-2022 走看看