bzoj 2961
根据“点在圆内”关系,列出点P(x0,y0)在圆C(x,y)内的关系:
(x-x0)^2+(y-y0)^2 <= x^2+y^2
化简得:
2*x0*x+2*y0*y >= x0^2+y0^2
然后我们就可以把一个点当成一条线,一个圆当成一个点,通过上面的表达式来转换,这样“点在圆内”的关系就转化成了“点在半平面内”的关系。这样原问题就转化成了不断的加点,然后询问是否所有点都在某个半平面中。
这个东西因为“某一个点在不在半平面中”对”所有点都在半平面中“的答案贡献独立(前者拥有一票否决权),又没有强制在线,所以可以使用对时间分治的思想,以多一个log的复杂度将”边加点边询问问题“变成”先把所有点都加进去,再询问问题“,而后者可以在O(nlogn)时间复杂度内搞定,所以可以在O(nloglog)的时间复杂度内解决。
这道题开始看错题的限制了,题目中限制的是圆心坐标的范围,没有限制询问点坐标的范围,所以就挂了。
/**************************************************************
Problem: 2961
User: idy002
Language: C++
Result: Accepted
Time:6708 ms
Memory:96872 kb
****************************************************************/ #include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#define N 500010
#define eps 1e-10
using namespace std; int sg( double x ) { return (x>-eps)-(x<eps); }
struct Vector {
double x, y;
void read() {
scanf( "%lf%lf", &x, &y );
}
Vector(){}
Vector( double x, double y ):x(x),y(y){}
Vector operator+( const Vector &b ) const { return Vector(x+b.x,y+b.y); }
Vector operator-( const Vector &b ) const { return Vector(x-b.x,y-b.y); }
Vector operator*( double b ) const { return Vector(x*b,y*b); }
Vector operator/( double b ) const { return Vector(x/b,y/b); }
double operator^( const Vector &b ) const { return x*b.y-y*b.x; }
double operator&( const Vector &b ) const { return x*b.x+y*b.y; }
double ang() { return atan2l(y,x); }
bool operator<( const Vector &b ) const {
return sg(x-b.x)< || (sg(x-b.x)== && sg(y-b.y)<);
}
};
typedef Vector Point;
struct Line {
Point p;
Vector u;
double ang;
int id;
bool ok;
void read( int id ) {
double x, y;
double a, b, c;
scanf( "%lf%lf", &x, &y );
a=x+x, b=y+y;
c=x*x+y*y; if( sg(a)== && sg(b)== ) {
p.x = p.y = 0.0;
u.x = 1.0;
u.y = 0.0;
} else {
if( sg(a)!= )
p.x = c/a, p.y = 0.0;
else
p.x = 0.0, p.y = c/b;
u.x = -b, u.y = a;
if( sg(u^(Point(0.0,0.0)-p))>= )
u.x=-u.x, u.y=-u.y;
} ok = true;
this->id = id;
ang = u.ang();
}
};
struct Job {
int opt;
Point pt;
Line ln;
void read( int id ) {
scanf( "%d", &opt );
if( opt== ) pt.read();
else ln.read(id);
}
}; int n;
Job job[N];
int ans[N];
Point cvx[N];
double lang[N]; bool onleft( Line &l, Point &p ) { // <=
return sg( l.u^(p-l.p) ) >= ;
}
bool onleft( Point &a, Point &b, Point &p ) { // <
return sg( (b-a)^(p-a) ) > ;
}
int convex( vector<Point> &p ) {
sort( p.begin(), p.end() );
int n=p.size();
int m;
cvx[m=] = p[];
for( int i=; i<n; i++ ) {
while( m> && !onleft(cvx[m-],cvx[m],p[i]) ) m--;
cvx[++m] = p[i];
}
int k=m;
for( int i=n-; i>=; i-- ) {
while( m>k && !onleft(cvx[m-],cvx[m],p[i]) ) m--;
cvx[++m] = p[i];
}
return m; // n>=2
}
void binary( int lf, int rg, vector<Point> &vp, vector<Line> &vn ) {
if( lf==rg ) {
if( job[lf].opt== )
vp.push_back( job[lf].pt );
else
vn.push_back( job[lf].ln );
return;
}
vector<Point> lvp;
vector<Line> rvn;
int mid=(lf+rg)>>;
binary( lf, mid, lvp, vn );
binary( mid+, rg, vp, rvn );
//--
Point kpt;
if( lvp.empty() || rvn.empty() ) {
// do nothing
} else if( lvp.size()== ) {
for( int t=; t<rvn.size(); t++ ) {
if( !rvn[t].ok ) continue;
if( !onleft(rvn[t],lvp[]) )
rvn[t].ok = false;
}
} else {
int n = convex( lvp );
for( int t=; t<n; t++ )
lang[t] = (cvx[(t+==n?:t+)]-cvx[t]).ang();
int vid = ;
for( int t=; t<n; t++ )
if( lang[t]>lang[(t+==n?:t+)] ) {
vid = (t+==n?:t+);
break;
}
rotate( cvx, cvx+vid, cvx+n );
rotate( lang, lang+vid, lang+n );
for( int t=; t<rvn.size(); t++ ) {
if( !rvn[t].ok ) continue;
int tt;
if( rvn[t].ang<=lang[] || rvn[t].ang>=lang[n-] ) {
tt = ;
} else {
int lf=, rg=n-;
while( lf<rg ) {
int mid=(lf+rg)>>;
if( lang[mid]>rvn[t].ang ) {
rg = mid;
} else {
lf = mid+;
}
}
tt = lf;
}
int pt = tt==?n-:tt-;
int nt = tt==n-?:tt+;
if( !onleft(rvn[t],cvx[tt])
||!onleft(rvn[t],cvx[pt])
||!onleft(rvn[t],cvx[nt]) ) {
rvn[t].ok=false;
}
}
}
//--
for( int t=; t<lvp.size(); t++ )
vp.push_back( lvp[t] );
for( int t=; t<rvn.size(); t++ )
vn.push_back( rvn[t] );
}
int main() {
scanf( "%d", &n );
bool ok = false;
for( int i=; i<=n; i++ ) {
job[i].read(i);
job[i].ln.ok = ok;
if( job[i].opt== ) ok=true;
}
vector<Line> vn;
vector<Point> vp;
binary( , n, vp, vn );
for( int i=; i<=n; i++ )
ans[i] = -;
for( int t=; t<vn.size(); t++ )
ans[vn[t].id] = vn[t].ok;
for( int i=; i<=n; i++ ) {
if( ans[i]==- ) continue;
printf( "%s\n", ans[i] ? "Yes" : "No" );
}
}
bzoj 2961的更多相关文章
- bzoj 2961 共点圆 cdq+凸包+三分
题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...
- zhengrui集训笔记2
Day_6 计算几何 点积\Large 点积点积 叉积\Large 叉积叉积 极角\Large 极角极角 < π\piπ :叉积判断 else :atan2 旋转\Large 旋转旋转 左乘第一 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- 让arch阻止某个软件包的升级
我更新了eclipse-java Mars版本的,感觉特别的卡,而且还有好多bug,不知道为什么,因此我去官网下载了luna版本的eclipse的安装包,不知道怎么下载的点击这里,然后安装luna版本 ...
- 读书笔记 effective c++ Item 52 如果你实现了placement new,你也要实现placement delete
1. 调用普通版本的operator new抛出异常会发生什么? Placement new和placement delete不是C++动物园中最常遇到的猛兽,所以你不用担心你对它们不熟悉.当你像下面 ...
- JUnit基本介绍
一.什么是单元测试 单元测试(Unit Testing)是指在计算机编程中,针对程序模块来进行正确性检验的测试工作.单元测试的特点如下: ※ 程序单元是应用最小的可测试部件,通常采用基于类或者类的方 ...
- Failed to load class "org.slf4j.impl.StaticLoggerBinder"
调试程序出现如下错误: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Default ...
- Java基础82 jsp中的EL表达式(网页知识)
1.EL表达式的作用 EL表达式的作用:向浏览器输出域对象中的变量值或者表达式计算结果.语法:${变量或者表达式} 注: Jsp的核心语法:jsp的表达式<%= %>和jsp的脚本< ...
- java基础52 编码与解码
1.解码与编码的含义 编码:把看得懂的字符变成看不懂的码值,这个过程就叫编码 解码:根据码值查到相对应的字符,我们把这个过程就叫解码 注意:编码与解码时,我们一般使用统一的码表,否则非常容易出现 ...
- lucene-利用内存中索引和多线程提高索引效率
转载地址: http://hi.baidu.com/idoneing/item/bc1cb914521c40603e87ce4d 1.RAMDirectory和FSDirectory对比 RAMDir ...
- HOG目标检测
用HOG进行行人检测时,需要用训练好的支持向量机来对图片进行分类,在opencv中,支持向量机已经训练好,但自己来训练支持向量机才能更好的体会这一过程. 参考:http://blog.csdn.net ...
- [新手]在macOS环境下安装xdebug
使用环境 masOS 10.12 使用MAMP安装的PHP环境 在新安装的系统中,安装xdebug,遇到了一些小问题; P.S. 重新按照xdebug官网的指南安装了一次,把上次安装失败的xd ...
- 毕设demo写好
2015年1月20日 14:41:47 阶段性暂停!! 把运行结果截图给了老师,老师说先整理下文档,然后下学期来了再部署到服务器上. 那么,下学期来了,估计也要把Epm和CR1000什么的搞好了. 先 ...