离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度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\n", 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,纵坐标均大于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

HINT

6.47

5.84

4.47

数据范围:

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

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

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

Source

BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )的更多相关文章

  1. 【题解】P2521 [HAOI2011]防线修建(动态凸包)

    [题解]P2521 [HAOI2011]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...

  2. 【bzoj2300】【Luogu P2521】 [HAOI2011]防线修建 动态凸包,平衡树,Set

    一句话题意:给你一个凸包,每次可以插入一个点或者询问周长. 动态凸包裸题嘛,用\(Set\)实现.最初每个点坐标做乘三处理,便于取初始三角形的重心作为凸包判定原点. #include <bits ...

  3. bzoj 2300 [HAOI2011]防线修建 set动态维护凸包

    题目大意 动态删点,求凸包周长 分析 反过来变成动态加点 用set维护平衡树 具体是找到凸包上左右两点 拆开 就可以把左边当作顺时针求的一个凸包,右边当作逆时针求的一个凸包,像栈那样出set就好了 注 ...

  4. bzoj 2300: [HAOI2011]防线修建 凸包

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2300 题解 这道题让我们维护一个支持动态删除点的上凸壳 并且告诉了我们三个一定不会被删除 ...

  5. bzoj 2300 : [HAOI2011]防线修建

    set动态维护凸包 #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  6. BZOJ 2300 [HAOI2011]防线修建 ——计算几何

    只需要倒着插入,然后维护一个凸包就可以了. 可以用来学习set的用法 #include <map> #include <set> #include <cmath> ...

  7. 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)

    2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...

  8. bzoj2300#2300. [HAOI2011]防线修建

    题解:带删点的维护凸包,1.删点2.查询凸包周长 题解:倒着做就成了带加点的维护凸包,加点时维护一下周长就没了 //#pragma GCC optimize(2) //#pragma GCC opti ...

  9. bzoj千题计划236:bzoj2300: [HAOI2011]防线修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> ...

随机推荐

  1. Android中API建议的方式实现SQLite数据库的增、删、改、查的操作

    package com.examp.use_SQLite.dao; import java.util.ArrayList; import java.util.List; import android. ...

  2. android VoiceRecognition 语音识别并打印到列表上

    package com.example.wenandroid; import java.util.ArrayList; import java.util.List; import android.ap ...

  3. 怎样调通微信支付及微信发货通知接口(Js API)

    怎样调通微信支付及微信发货通知接口(Js API) 微信支付提供了一个支付測试页面,微信支付正式使用须要測通支付.发货通知接口 .告警接口.维权接口.告警接口.维权接口非常easy.支付界面调通也相对 ...

  4. Swift中编写单例的正确方式

    在之前的帖子里聊过状态管理有多痛苦,有时这是不可避免的.一个状态管理的例子大家都很熟悉,那就是单例.使用Swift时,有许多方法实现单例,这是个麻烦事,因为我们不知道哪个最合适.这里我们来回顾一下单例 ...

  5. C语言中为什么不能把char**赋给const char**

    这是我在知乎回答的一个问题. 这个问题是C中的一个深坑,首先说结论: char ** 和 const char ** 是两个不相容(incompatible)的类型,能够理解为不能直接赋值 在C11的 ...

  6. 如何更快速加载你的JS页面

    确保代码尽量简洁 不要什么都依赖JavaScript.不要编写重复性的脚本.要把JavaScript当作糖果工具,只是起到美化作用.别给你的网站添加大量的JavaScript代码.只有必要的时候用一下 ...

  7. AngularJs(八) 过滤器filter创建

    大纲 示例 过滤器的使用 创建过滤器 demo 这是整个示例demo 1.filter.js文件 angular.module("exampleApp", []) .constan ...

  8. JAVA 可视化分析工具 第12节

    JAVA 可视化分析工具  第12节 经过前几章对堆内存以及垃圾收集机制的学习,相信小伙伴们已经建立了一套比较完整的理论体系!那么这章我们就根据已有的理论知识,通过可视化工具来实践一番. 我们今天要讲 ...

  9. c++标准库函数equal_range()

    首先容器(vector)的中的元素是有序的.这里就不讲容器元素类型为内置的类型的用法,因为比较容易. 重点讲一下容器元素类型为自定义类型时的用法.当我们把自定义类型的数据成员的类型的值传给equal_ ...

  10. 整个网站灰度显示css代码

    body *{ -webkit-filter: grayscale(100%); /* webkit */ -moz-filter: grayscale(100%); /*firefox*/ -ms- ...