bzoj 1249: SGU277 HERO
时间:2020-01-09
本文章向大家介绍bzoj 1249: SGU277 HERO,主要包括bzoj 1249: SGU277 HERO使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题意
这是极角序维护凸包。
找一个点作为基准点,我选的是\(p1\)和\(p_2,p_3\)的中点的中点。
用\(set\)维护凸包,内部按照极角排序。
插入一个点:
如果之前存在就不插入。
不然就找到它的前驱\(pre\)和后继\(nxt\),之后不断弹掉两边的点,中途维护下面积即可。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
const double eps=1e-8;
int n,cnt=3;
ll ans;
struct Point
{
double x,y;
inline double len(){return x*x+y*y;}
Point operator+(const Point& a)const{return (Point){x+a.x,y+a.y};}
Point operator-(const Point& a)const{return (Point){x-a.x,y-a.y};}
Point operator*(const double& k){return (Point){x*k,y*k};}
Point operator/(const double& k){return (Point){x/k,y/k};}
double operator*(const Point& a)const{return x*a.y-y*a.x;}
double operator&(const Point& a)const{return x*a.x+y*a.y;}
};
Point st;
Point p[5];
inline int dcmp(double x)
{
if(fabs(x)<=eps)return 0;
return x<0?-1:1;
}
bool operator<(Point a,Point b)
{
Point tmpa=a-st,tmpb=b-st;
if(dcmp(tmpa.y*tmpb.y)<0)return dcmp(tmpa.y-tmpb.y)<0;
if(!dcmp(tmpa.y)&&!dcmp(tmpb.y)&&dcmp(tmpa.x*tmpb.x)<0)return dcmp(tmpa.x-tmpb.x)<0;
double det=tmpa*tmpb;
if(dcmp(det)!=-0)return dcmp(det)>0;
return dcmp(a.len()-b.len())>0;
}
set<Point>s;
inline Point getpre(Point a)
{
set<Point>::iterator it=s.find(a);
if(it==s.begin())it=s.end();
return *(--it);
}
inline Point getnxt(Point a)
{
set<Point>::iterator it=s.find(a);
if((++it)==s.end())it=s.begin();
return *it;
}
inline ll calc(Point a,Point b)
{
a=a-p[1],b=b-p[1];
return abs((ll)a.x*(ll)b.y-(ll)a.y*(ll)b.x);
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
for(int i=1;i<=3;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
st=(p[1]+(p[2]+p[3])*0.5)*0.5;
ans=calc(p[2],p[3]);
for(int i=1;i<=3;i++)s.insert(p[i]);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
Point a;scanf("%lf%lf",&a.x,&a.y);
if(s.count(a)){printf("%lld\n",ans);continue;}
s.insert(a);
Point pre=getpre(a),nxt=getnxt(a);
if(dcmp((a-pre)*(nxt-a))<0)
{
s.erase(a);
printf("%lld\n",ans);
continue;
}
cnt++;
ans-=calc(pre,nxt);
Point b=getpre(pre);
while(cnt>3&&dcmp((pre-b)*(a-pre))<=0)
{
ans-=calc(b,pre);
s.erase(pre);cnt--;
pre=b,b=getpre(pre);
}
b=getnxt(nxt);
while(cnt>3&&dcmp((nxt-a)*(b-nxt))<=0)
{
ans-=calc(nxt,b);
s.erase(nxt);cnt--;
nxt=b,b=getnxt(nxt);
}
ans+=calc(pre,a)+calc(a,nxt);
printf("%lld\n",ans);
}
return 0;
}
原文地址:https://www.cnblogs.com/nofind/p/12172505.html
- jquery.mobile手机网页简要
- 跟张志东深聊腾讯的“进化力”
- 详解微信小程序如何实现流程进度功能
- silverlight:如何在图片上挖个洞?
- .NET Core系列 : 1、.NET Core 环境搭建和命令行CLI入门
- mysqldump数据导出问题和客户端授权后连接失败问题
- Android置底一个View后运行报错
- 温故而知新:设计模式之抽象工厂(AbstractFactory)
- mysql操作命令梳理(1)-索引
- Linux下对lvm逻辑卷分区大小的调整(针对xfs和ext4不同文件系统)
- centos6.5虚拟机安装后,没有iptables配置文件
- 温故而知新:设计模式之Builder
- 温故而知新:设计模式之单件模式(Singleton)
- sudo命令使用的几个场景
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JavaScript进阶教程(5)-一文让你搞懂作用域链和闭包
- JavaScript进阶教程(6)—硬核动图让你轻松弄懂递归与深浅拷贝
- Spring:JDBC Template,声明式事务
- Spring:讲解编程题
- SpringMVC:基本应用
- SpringMVC:进阶
- SpringMVC:SSM 整合
- 12 | Tornado源码分析:BaseIOStream 对象(上)
- 数据一致性校验及数据同步,运维必看
- Windows使用scoop包管理器安装RabbitMQ
- 深入理解web协议(二):DNS、WebSocket
- Elasticsearch:使用 function_score 及 soft_score 定制搜索结果的分数
- Elasticsearch:基于 Vector 的打分
- RocketMQ的发送模式和消费模式
- 实现一个简单的JS效果