zoukankan      html  css  js  c++  java
  • BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )

    离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN)

    -----------------------------------------------------------------------

    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
     
    using namespace std;
     
    #define sqr(x) ((x) * (x))
    #define Dist(a, b) sqrt(sqr(a.x - b.x) + sqr(a.y - b.y))
    #define K(a, b) ((double) (a.y - b.y) / (a.x - b.x))
     
    const int maxn = 100009;
    const double eps = 1e-9;
     
    double ans[maxn], res;
    int N, Q, q[maxn], n;
    bool F[maxn];
     
    inline int read() {
    char c = getchar();
    for(; !isdigit(c); c = getchar());
    int ret = 0;
    for(; isdigit(c); c = getchar())
    ret = ret * 10 + c - '0';
    return ret;
    }
     
    struct P {
    int x, y;
    P(int _x = 0, int _y = 0) : x(_x), y(_y) {
    }
    bool operator < (const P &t) const {
    return x < t.x || (x == t.x && y < t.y);
    }
    bool operator == (const P &t) const {
    return x == t.x && y == t.y;
    }
    bool operator != (const P &t) const {
    return x != t.x || y != t.y;
    }
    } p[maxn];
     
    struct Node {
    Node *ch[2];
    P o;
    int r;
    } pool[maxn], *pt, *Root, *Null;
     
    void Init_Treap() {
    pt = pool;
    Null = pt++;
    Null->ch[0] = Null->ch[1] = Null;
    Root = Null;
    }
     
    Node* newNode(P o) {
    pt->o = o;
    pt->r = rand();
    pt->ch[0] = pt->ch[1] = Null;
    return pt++;
    }
     
    void Rotate(Node*&t, int d) {
    Node* o = t->ch[d ^ 1];
    t->ch[d ^ 1] = o->ch[d];
    o->ch[d] = t;
    t = o;
    }
     
    void Delete(Node*&t, P o) {
    int d = (t->o == o ? -1 : (t->o < o));
    if(d == -1) {
    if(t->ch[0] != Null && t->ch[1] != Null) {
    int _d = (t->ch[0]->r > t->ch[1]->r);
    Rotate(t, _d), Delete(t->ch[_d], o);
    } else
    t = (t->ch[0] != Null ? t->ch[0] : t->ch[1]);
    } else
    Delete(t->ch[d], o);
    }
     
    void Insert(Node*&t, P o) {
    if(t == Null) {
    t = newNode(o);
    } else {
    int d = (t->o < o);
    Insert(t->ch[d], o);
    if(t->ch[d]->r > t->r) Rotate(t, d ^ 1);
    }
    }
     
    Node* Pred(P o) {
    Node* ret;
    for(Node* t = Root; t != Null; ) if(t->o < o) {
    ret = t, t = t->ch[1];
    } else
    t = t->ch[0];
    return ret;
    }
     
    Node* Succ(P o) {
    Node* ret;
    for(Node* t = Root; t != Null; ) if(o < t->o) {
    ret = t, t = t->ch[0];
    } else
    t = t->ch[1];
    return ret;
    }
     
    bool chk(P o) {
    for(Node* t = Root; t != Null; ) {
    if(t->o.x == o.x) return o.y > t->o.y;
    t = (t->o < o ? t->ch[1] : t->ch[0]);
    }
    return true;
    }
     
    void Add(P o) {
    Node *L = Pred(o), *R = Succ(o), *LL, *RR;
    if(R->o.x == o.x) return;
    if(L->o.x == o.x) {
    LL = Pred(L->o);
    res += Dist(LL->o, o) + Dist(R->o, o) - Dist(L->o, R->o) - Dist(LL->o, L->o);
    Delete(Root, L->o);
    L = Pred(o);
    } else if(K(R->o, o) - K(L->o, o) > eps) {
    return;
    } else 
    res += Dist(L->o, o) + Dist(R->o, o) - Dist(L->o, R->o);
    Insert(Root, o);
    if(L->o != P(0, 0)) {
    LL = Pred(L->o);
    while(L->o != P(0, 0) && K(o, L->o) - K(LL->o, L->o) > eps) {
    Delete(Root, L->o);
    res += Dist(LL->o, o) - Dist(LL->o, L->o) - Dist(L->o, o);
    L = LL, LL = Pred(L->o);
    }
    }
    if(R->o != P(n, 0)) {
    RR = Succ(R->o);
    while(R->o != P(n, 0) && K(RR->o, R->o) - K(R->o, o) > eps) {
    Delete(Root, R->o);
    res += Dist(RR->o, o) - Dist(RR->o, R->o) - Dist(R->o, o);
    R = RR, RR = Succ(R->o);
    }
    }
    }
     
    void Work() {
    for(int i = 0; i < N; i++)
    if(!F[i]) Add(p[i]);
    for(int i = Q; i--; ) if(~q[i]) {
    if(F[q[i]]) Add(p[q[i]]);
    F[q[i]] = false;
    } else
    ans[i] = res;
    for(int i = 0; i < Q; i++)
    if(!~q[i]) printf("%.2lf ", ans[i]);
    }
     
    void Init() {
    n = read();
    int x = read(), y = read();
    Init_Treap();
    Insert(Root, P(0, 0));
    Insert(Root, P(n, 0));
    Insert(Root, P(x, y));
    res = sqrt(x * x + y * y) + sqrt(sqr(x - n) + y * y);
    N = read();
    for(int i = 0; i < N; i++)
    p[i].x = read(), p[i].y =read();
    memset(F, 0, sizeof F);
    Q = read();
    for(int i = 0; i < Q; i++) if((q[i] = read()) != 2) {
    F[--(q[i] = read())] = true;
    } else
    q[i] = -1;
    }

      

    int main() {
    Init();
    Work();
    return 0;
    }

    ----------------------------------------------------------------------- 

    2300: [HAOI2011]防线修建

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 623  Solved: 330
    [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,纵坐标均大于0A国有一个不在(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

    HINT



    6.47



    5.84



    4.47



     



    数据范围:



    30%的数据m<=1000,q<=1000



    100%的数据m<=100000,q<=200000,n>1



    所有点的坐标范围均在10000以内, 数据保证没有重点

    Source

  • 相关阅读:
    .NETframework的EF框架学习报错之datetime 数据类型
    String...的用法
    存储过程从入门到熟练(c#篇)
    售前如何做好产品演示
    华为演讲培训售前人员重点学习
    report services 报表开发和部署,集成到解决方案中 全解析
    在Asp.net用C#建立动态Excel(外文翻译)
    NET(C#)连接各类数据库集锦
    在SourceForge.net上如何使用TortoiseCVS
    用C#实现在线升级
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5137037.html
Copyright © 2011-2022 走看看