• BZOJ [HAOI2011]防线修建(动态凸包)


    听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了。

    先说下动态凸包怎么写吧,搞棵平衡树存上下凸壳然后每次插入一个点就往他左右维护看是否满足凸性否则就弹出,就是这么简单

    这道题就是删点然后询问凸壳,那么离线反着做就行了

    出题人还是挺良心的直接让你维护上凸壳就行了,还不用管边界条件

    用set打了一下,比较慢但还是挺好打的= =

    换新blog挺多功能得试试的,现在想搞个像HZWER的那个球还有一个虾米等有时间试试(当然还有头像!!!)

    好了不多说了发完睡觉了= =

    CODE:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<set>
     6 #include<cmath>
     7 using namespace std;
     8 typedef pair<int,int> ii;
     9 typedef set<ii>::iterator iter;
    10 #define fi first
    11 #define se second
    12 #define sqr(x) ((x)*(x))
    13 inline double dist(ii u,ii v) {return sqrt(sqr(u.fi-v.fi)+sqr(u.se-v.se));}
    14 inline int cross(ii x,ii y,ii z) {
    15     return (y.fi-x.fi)*(z.se-x.se)-(y.se-x.se)*(z.fi-x.fi);
    16 }
    17 set<ii> gap;
    18 #define maxn 201000
    19 int a[maxn][2],c[maxn][2];
    20 bool b[maxn];
    21 double sum,ans[maxn];
    22 inline void del(iter x){
    23     iter u=x,v=x;
    24     u--,v++;
    25     sum-=dist(*u,*x)+dist(*x,*v);
    26     sum+=dist(*u,*v);
    27     gap.erase(x);
    28 }
    29 inline void ins(ii x){
    30     iter it=gap.upper_bound(x);
    31     --it;
    32     iter v=it,u;++v;
    33     if (cross(*it,x,*v)>=0) return;
    34     gap.insert(x);
    35     it=gap.find(x);
    36     v=it,u=it;
    37     --u,++v;
    38     sum+=dist(*u,*it)+dist(*it,*v);
    39     sum-=dist(*u,*v);
    40     for (iter v=it,u;;v=it){
    41         ++v;u=v;++v;
    42         if (v==gap.end()) break;
    43         if (cross(*it,*u,*v)<0) break;
    44         del(u);
    45     }
    46     for (iter v=it,u;;v=it){
    47         --v;
    48         if (v==gap.begin()) break;
    49         u=v;--v;
    50         if (cross(*v,*u,*it)<0) break;
    51         del(u);
    52     }
    53 }
    54 int main(){
    55     int n,m,q;
    56     scanf("%d%d%d",&n,&a[0][0],&a[0][1]);
    57     scanf("%d",&m);
    58     for (int i=1;i<=m;i++) scanf("%d%d",a[i],a[i]+1);
    59     scanf("%d",&q);
    60     for (int i=1;i<=q;i++) {
    61         scanf("%d",c[i]);
    62         if (c[i][0]==1) scanf("%d",c[i]+1),b[c[i][1]]=1;
    63     }
    64     gap.insert(ii(0,0));
    65     gap.insert(ii(n,0));
    66     sum=n;
    67     for (int i=0;i<=m;i++) if (!b[i]) ins(ii(a[i][0],a[i][1]));
    68     for (int i=q;i;i--) {
    69         if (c[i][0]==1) ins(ii(a[c[i][1]][0],a[c[i][1]][1]));
    70         else ans[i]=sum;
    71     }
    72     for (int i=1;i<=q;i++)
    73         if (ans[i]) printf("%.2lf
    ",ans[i]);
    74     return 0;
    75 }
  • 相关阅读:
    HTML技巧: 语义化你的代码
    css sprite
    Redis主从复制原理
    idea修改快捷键
    Ubuntu14.20 安装docker,创建centos6.7容器,并访问centos容器
    [转]SQL 中 with as 的用法
    ftp与sftp及sftp和scp的区别
    Linux top 命令
    Linux free 命令
    ubuntu 源方式 安装jdk
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4351954.html
Copyright © 2020-2023  润新知