zoukankan      html  css  js  c++  java
  • BZOJ 2300[HAOI2011]防线修建

    题面:

    2300: [HAOI2011]防线修建

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 960  Solved: 527
    [Submit][Status][Discuss]

    Description

    近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了。可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于A国的经费有限,所以希望你能帮忙完成如下的一个任务:
    1.给出你所有的A国城市坐标
    2.A国上层经过讨论,考虑到经济问题,决定取消对i城市的保护,也就是说i城市不需要在防线内了
    3.A国上层询问对于剩下要保护的城市,修建防线的总经费最少是多少
    你需要对每次询问作出回答。注意单位1长度的防线花费为1。
    A国的地形是这样的,形如下图,x轴是一条河流,相当于一条天然防线,不需要你再修建
    A国总是有两个城市在河边,一个点是(0,0),一个点是(n,0),其余所有点的横坐标均大于0小于n,纵坐标均大于0。A国有一个不在(0,0)和(n,0)的首都。(0,0),(n,0)和首都这三个城市是一定需要保护的。

    上图中,A,B,C,D,E点为A国城市,且目前都要保护,那么修建的防线就会是A-B-C-D,花费也就是线段AB的长度+线段BC的长度+线段CD的长度,如果,这个时候撤销B点的保护,那么防线变成下图 

    Input

    第一行,三个整数n,x,y分别表示河边城市和首都是(0,0),(n,0),(x,y)。
    第二行,一个整数m。
    接下来m行,每行两个整数a,b表示A国的一个非首都非河边城市的坐标为(a,b)。
    再接下来一个整数q,表示修改和询问总数。
    接下来q行每行要么形如1 i,要么形如2,分别表示撤销第i个城市的保护和询问。

    Output

    对于每个询问输出1行,一个实数v,表示修建防线的花费,保留两位小数

    Sample Input

    4 2 1
    2
    1 2
    3 2
    5
    2
    1 1
    2
    1 2
    2

    Sample Output

    6.47
    5.84
    4.47

    HINT

    m<=100000,q<=200000,n>1

    所有点的坐标范围均在10000以内, 数据保证没有重点
     
    将询问离线后就变成支持插入操作的动态凸包,用set维护。
      1 #include<stdio.h>
      2 #include<math.h>
      3 #include<set>
      4 #include<iostream>
      5 using namespace std;
      6 #define maxn 100001
      7 #define maxm 200001
      8 struct QAQ
      9 {
     10     int x,y;
     11     friend QAQ operator - (QAQ a,QAQ b)
     12     {
     13         return (QAQ){a.x-b.x,a.y-b.y};
     14     }
     15     friend int operator * (QAQ a,QAQ b)
     16     {
     17         return a.x*b.y-b.x*a.y;
     18     }
     19     bool operator < (const QAQ &a) const
     20     {
     21         return x<a.x||(x==a.x&&y<a.y);
     22     }
     23 }T_T[maxn];
     24 struct QWQ
     25 {
     26     double ans;
     27     int op,x;
     28 }TAT[maxm];
     29 bool book[maxn];
     30 int n,m;
     31 double ans;
     32 double dis(QAQ a,QAQ b)
     33 {
     34     return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
     35 }
     36 set<QAQ>ss;
     37 void insert(int p,int q)
     38 {
     39     QAQ t=(QAQ){p,q};
     40     set<QAQ>::iterator r=ss.lower_bound(t),l=r,s;
     41     l--;
     42     if((*r-*l)*(t-*l)<0)
     43         return ;
     44     ans-=dis(*l,*r);
     45     while(1)
     46     {
     47         s=r;
     48         r++;
     49         if(r==ss.end())
     50             break;
     51         if((*r-t)*(*s-t)>0)
     52             break;
     53         ans-=dis(*r,*s);
     54         ss.erase(s);
     55     }
     56     while(l!=ss.begin())
     57     {
     58         s=l;
     59         l--;
     60         if((*s-t)*(*l-t)>0)
     61             break;
     62         ans-=dis(*s,*l);
     63         ss.erase(s);
     64     }
     65     ss.insert(t);
     66     l=r=s=ss.find(t);
     67     l--,r++;
     68     ans+=dis(*l,*s)+dis(*r,*s);
     69 }
     70 int main()
     71 {
     72     int a,b,T;
     73     QAQ t1,t2,t3;
     74     scanf("%d%d%d",&n,&a,&b);
     75     t1=(QAQ){0,0};
     76     t2=(QAQ){n,0};
     77     t3=(QAQ){a,b};
     78     ss.insert(t1);
     79     ss.insert(t2);
     80     ss.insert(t3);
     81     scanf("%d",&T);
     82     ans+=dis(t1,t3)+dis(t2,t3);
     83     for(int i=1;i<=T;i++)
     84         scanf("%d%d",&T_T[i].x,&T_T[i].y);
     85     scanf("%d",&m);
     86     for(int i=1;i<=m;i++)
     87     {
     88         scanf("%d",&TAT[i].op);
     89         if(TAT[i].op==1)
     90         {
     91             scanf("%d",&TAT[i].x);
     92             book[TAT[i].x]=true;
     93         }
     94     }
     95     for(int i=1;i<=T;i++)
     96         if(!book[i])
     97             insert(T_T[i].x,T_T[i].y);
     98     for(int i=m;i>=1;i--)
     99     {
    100         if(TAT[i].op==1)
    101             insert(T_T[TAT[i].x].x,T_T[TAT[i].x].y);
    102         else
    103             TAT[i].ans=ans;
    104     }
    105     for(int i=1;i<=m;i++)
    106         if(TAT[i].op==2)
    107             printf("%.2lf
    ",TAT[i].ans);
    108 }
    BZOJ 2300
     
  • 相关阅读:
    用call/apply实现bind
    FED1 修改 this 指向(中等)
    46. 全排列(中等)
    JavaScript 用七种方式教你判断一个变量是否为数组类型(转)
    179. 最大数(中等)
    125. 验证回文串(简单)
    执行git pull命令时出错
    前端修改滚动条样式
    js实现每日定时任务
    Vue实现验证码控件
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7304860.html
Copyright © 2011-2022 走看看