根据“点在圆内”关系,列出点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的更多相关文章

  1. bzoj 2961 共点圆 cdq+凸包+三分

    题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...

  2. zhengrui集训笔记2

    Day_6 计算几何 点积\Large 点积点积 叉积\Large 叉积叉积 极角\Large 极角极角 < π\piπ :叉积判断 else :atan2 旋转\Large 旋转旋转 左乘第一 ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  2. 【codeforces】【比赛题解】#872 CF Round #440 (Div.2)

    链接. [A]寻找漂亮数字 题意: 给定了两列非零数字.我们说一个数是漂亮的,当它的十进制表达中有至少一个数从数列一中取出,至少有一个数从数列二中取出.最小的漂亮数字是多少? 输入: 第一行两个数\( ...

  3. centos7 部署 seafile

    =============================================== 2018/5/13_第1次修改                       ccb_warlock == ...

  4. 分别使用docx4j,jacob将文字与图片插入word中书签位置

    项目中需要将一段文字,与人员的签名(图片)插入到上传的word中,上网查询了一下,有许多种方式可以向word中插入文字,发现docx4j与jacob都为比较常见的解决方案,于是就先使用的docx4j进 ...

  5. elasticsearch5.5

    1.不能以root用户运行 groupadd es          #增加es组 useradd es -g es -p pwd          #增加es用户并附加到es组 chown -R e ...

  6. 关于在调用JAVAFX相关包时遇到Access restriction: The type 'Application' is not API (restriction on required library)的解决方法

    点击工具栏的Project->Properties->Java Build Path->Libraries-> 双击第一项 点击Add添加允许javafx 然后就不会报错了

  7. HDU 4763 Theme Section(KMP+枚举公共前后缀)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目大意: 给你一个字符串s,存在一个子串E同时出现在前缀.中间.后缀,即EAEBE这种模式,A ...

  8. Qt通过ODBC来操作Excel

    示例代码: #include<QtCore/QCoreApplication> #include<QtSql> #include<QObject> #include ...

  9. 使用文本用户界面(NMTUI)进行网络配置

    NetworkManager 文本用户界面(TUI)工具 nmtui 可提供一个文本界面配置由 NetworkManager 控制的网络.该工具包含在 NetworkManager-tui 子软件包中 ...

  10. Jenkins在Linux环境安装

    Jenkins介绍 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. 安装环境 操作系统:lin ...