题目大意:给你m+3个点,有q个操作,每次要么询问当前点集构所构成的上凸壳总长度,要么在当前点集中删除一个点。

这题是吼题啊!!!

刚开始想着如何正常地做,考虑过用线段树维护一个区间内的凸包,发现并不行,要另请高明。

后来发现,这题并没有强制在线要求,我们不妨将所有的询问反过来处理。首先将从头到尾都没有被删除的点加入该凸包,然后将询问倒序处理,将原先的删点操作改为加点操作,随后动态维护该凸包并维护上凸壳总长度,需输出的答案压入一个栈中,最后逐个弹出输出即可。

至于如何动态维护凸包。本题有一个很特殊的条件:所有点坐标的x,y值均大于0,且必有一个点坐标为(0,0)。故我们可以用一个set维护当前在凸包上的点,当需要加入一个点k时,借助lower_bound找到与该点相邻夹角的两个点,直接进行维护即可。实现细节较为复杂,强烈建议先工整地将维护方法写在草稿纸上!!

PS:这次发现set容器的iterator有一些神奇的性质,假定有一个迭代器指针it,其后继为it1,在it未更新时,若有一个元素插入在it和it1之间,那么it1仍将认为其后继为it1而非新插入的元素,需要用某些方法更新下it(没有1a的元凶)

 #include<bits/stdc++.h>
#define M 210000
using namespace std;
struct node{
int x,y; node(){x=y=;}
node(int xx,int yy){x=xx; y=yy;}
friend node operator -(node a,node b){return node(a.x-b.x,a.y-b.y);}
friend int operator *(node a,node b){
return a.y*b.x-a.x*b.y;
}
friend bool operator <(node a,node b){
if(a.x==&&a.y==) return ;
if(b.x==&&b.y==) return ;
if(a.x*b.y==a.y*b.x) return a.x<b.x;
return a.y*b.x<a.x*b.y;
}
}a[M];
set<node> s; int n,x,y,m,op[M]={},id[M]={}; bool vis[M]={};
int cj(node a,node b,node c){return (b-a)*(c-a);}
double dis(node a,node b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
double ans=; void ins(node k){
set<node>::iterator now,nowm,nown,pre;
nown=nowm=now=s.upper_bound(k);
now--; nowm--; nowm--;
while(cj(*nowm,*now,k)>){
ans=ans-dis(*nown,*now)-dis(*now,*nowm)+dis(*nown,*nowm);
pre=now; *now--;
s.erase(pre);
if(nowm==s.begin()) break;
*nowm--;
}
if(cj(*now,k,*nown)>) return;
ans=ans-dis(*nown,*now)+dis(*nown,k)+dis(*now,k);
s.insert(k);
nowm=now=nown=s.find(k);
now++; nown++; nown++;
while(cj(*nowm,*now,*nown)>&&nown!=s.end()){
ans=ans-dis(*nown,*now)-dis(*now,*nowm)+dis(*nown,*nowm);
pre=now; *now++; *nown++;
s.erase(pre);
}
}
double ansp[M]={};int use=;
int main(){
scanf("%d%d%d",&n,&x,&y);
s.insert(node(,)); s.insert(node(n,)); s.insert(node(x,y));
ans=dis(node(,),node(x,y))+dis(node(x,y),node(n,));
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d",op+i);
if(op[i]==) continue;
scanf("%d",id+i);
vis[id[i]]=;
}
for(int i=;i<=n;i++) if(!vis[i]) ins(a[i]);
for(int i=m;i;i--){
if(op[i]==) {ansp[++use]=ans; continue;}
if(!vis[id[i]]) continue;
ins(a[id[i]]); vis[id[i]]=;
}
while(use) printf("%.2lf\n",ansp[use--]);
}

【BZOJ2300】【HAOI2011】防线修建的更多相关文章

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

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

  2. BZOJ2300[HAOI2011]防线修建——非旋转treap+凸包(平衡树动态维护凸包)

    题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于 ...

  3. BZOJ2300: [HAOI2011]防线修建

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2300 (我只是在发以前写过的题.. 因为题目没说强制在线,所以离线乱搞就可以了.先把点删掉然后 ...

  4. 2019.02.21 bzoj2300: [HAOI2011]防线修建(set+凸包)

    传送门 题意:动态维护凸包周长. 思路: 见这篇求面积的吧反正都是一个套路. 代码: #include<bits/stdc++.h> #define int long long #defi ...

  5. 【BZOJ2300】[HAOI2011]防线修建 set维护凸包

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

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

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

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

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

  8. [luogu P2521] [HAOI2011]防线修建

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

  9. P2521 [HAOI2011]防线修建

    题目链接:P2521 [HAOI2011]防线修建 题意:给定点集 每次有两种操作: 1. 删除一个点 (除开(0, 0), (n, 0), 与指定首都(x, y)) 2. 询问上凸包长度 至于为什么 ...

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

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

随机推荐

  1. 20155207 2016-2017-2 《Java程序设计》第九周学习总结

    20155207 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立 ...

  2. 博客停更转战简书http://www.jianshu.com/u/7ac4047c9cfa

    博客停更转战简书 http://www.jianshu.com/u/7ac4047c9cfa

  3. 被弃用的php函数以及被那个代替

      原文链接 http://blog.csdn.net/a11085013/article/details/8937848   下面列举了部分被弃用的函数:      call_user_method ...

  4. BeanUtils.populate的方法的作用

    BeanUtils位于org.apache.commons.beanutils.BeanUtils下面,其方法populate的作用解释如下: 完整方法: BeanUtils.populate( Ob ...

  5. JedisPoolConfig解说

    版本一 今天发现Jedis 默认的连接方式 jedis=new Jedis(“localhost”,6379),老是发生connection timeout. 后来发现jedis类包还有一种可以设置最 ...

  6. MongoDB安装为Windows服务方法与注意事项

    MongoDB作为一个基于分布式文件存储的数据库,近两年大受追捧.数据灵活的存取方式和高效的处理使得它广泛用于互联网应用. 最近本人开始在Windows 32位平台下研究MongoDB的使用,为了方便 ...

  7. Java中的I/O 线程 网络

    Java学习总结--I/O,线程,网络题目整理 I/O 1.有什么理由必须要用字符流? 答:处理字符数据的语法更方便.自动化字符编码 2.插入哪些代码可以让下面的代码正确编译? Console con ...

  8. linux cpu过高原因及代码定位

    1. top命令查看CPU和内存占用率 top回车,然后按1 发现进程PID 35163 CPU和内存占用率都很高 top - 06:13:47 up  5:31,  1 user,  load av ...

  9. 20145209 2016-2017-2 《Java程序设计》第6周学习总结

    20145209 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 4.1 Y86指令集体系结构 •有8个程序寄存器:%eax.%ecx.%edx.%ebx.% ...

  10. ESP32应用程序的内存布局

    应用程序内存布局 ESP32芯片具有灵活的内存映射功能.本节介绍ESP-IDF在默认情况下如何使用这些功能. ESP-IDF中的应用程序代码可以放置在以下内存区域之一中. IRAM(指令RAM) ES ...