解方程题!

Description

Bessie学会了刺绣这种精细的工作。牛们在一片半径为d(1 <= d <= 50000)的圆形布上绣花. 它们一共绣了N (2 <= N <= 50000)条直线,每条直线连接布的边缘上的两个点(没有两条线通过边上同一个点)。 作为一只热爱数学的牛,Bessie 知道每条线的公式, ax + by + c = 0. a, b, 和 c 为整数(-1000000 <= a <= 1000000; -1000000 <= b <= 1000000; -1000000 <= c <= 1000000).没有两条线完全重合。 不幸的是, 一部分线不通过圆布的内部. 原点(0,0)在布的正中央, 所有边上的点离原点距离为d. 每条线的公式满足至少a,b中的一个非零. 对于牛来说,刺绣作品中线的交点越多,便越有价值。帮助Bessie计算在圆中相交的线的对数,也就是说交点与原点的距离小于d。注意如果三条线在圆内同一点相交,这算3对线。4线共点->6对线.

Input

第1行: 两个空格分开的数, N 和 d 第2..N+1行: 第 i+1 行包含第i条线的参数: a, b 和 c

Output

第1行: 一行,包含一个数,为在园内相交的线的对数.

Sample Input

2 1
1 0 0
0 1 0

输入说明:
两条直线x=0和y=0.

Sample Output

1

HINT

两条线在(0,0)相交, 明显离原点距离小于1.


题目分析

模型转化

$n=50000$的数据规模,$n^2$的枚举肯定不行。那么可以省去哪些枚举呢?

先考虑哪些线段才会相交。

因为对于一条直线,有效部分就只有与圆内的公共部分。所以我们只需要记录直线与圆的两个交点。

但是由于会出现如下图所示情况,

还需要把x轴坐标再映射一下。若$y<0$,则$L=-x-r$;反之$R=x+r$。

自然发现这样映射之后,圆上任意一点都有了唯一的映射值。

实际上就是变成了这样。

于是直线在圆内相交就等价于映射后的线段下相交(不包含)。

树状数组维护

如何处理相交但不包含的线段条数?

这里有一种挺妙的方法:先把线段按照左端点排序,这样保证了处理时左端点的有序。然后计算线段内的右端点个数。因为之前处理的线段左端点都是小于等于现在处理的左端点的,所以线段内的右端点个数就是与现在处理的线段的相交的线段条数。

这样子就可以离散化后用树状数组做了。

(树状数组好棒啊!)

 #include<bits/stdc++.h>
const int maxn = ; int n,d,cnt;
long long f[maxn<<],ans;
double t[maxn<<],xa,xb,ya,yb,a,b,c;
std::pair<double, double> mp[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int lowbit(int x){return x&-x;}
void add(int x){for (; x<maxn<<; x+=lowbit(x)) f[x]++;}
int query(int x)
{
int ret = ;
for (; x; x-=lowbit(x)) ret += f[x];
return ret;
}
double calc(double x, double y){return y < ?-x-d:x+d;}
int main()
{
n = read(), d = read();
for (int i=; i<=n; i++)
{
// int a = read(), b = read(), c = read();
scanf("%lf%lf%lf",&a,&b,&c);
bool cte = ;
xa = xb = ya = yb = ;
if (!a || !b){
if (!a){
double h = -c/b;
if (h*h-d*d > ) cte = ;
else{
xa = -sqrt(d*d*1.0-h*h), xb = -xa;
ya = yb = h;
}
}else{
double w = -c/a;
if (w*w-d*d > ) cte = ;
else{
xa = xb = w;
ya = sqrt(d*d*1.0-w*w), yb = -ya;
}
}
}else{
double equa = a*a+b*b*1.0, equb = *a*c*1.0, equc = c*c*1.0-b*b*d*d*1.0;
double delta = equb*equb*1.0-4.0*equa*equc;
if (delta < ) cte = ;
else{
xa = (-equb-sqrt(delta))/(2.0*equa);
xb = (-equb+sqrt(delta))/(2.0*equa);
ya = -(a*xa+c)/b;
yb = -(a*xb+c)/b;
}
}
if (cte) continue;
double L = calc(xa, ya), R = calc(xb, yb);
if (L > R) std::swap(L, R);
mp[++cnt] = std::make_pair(L, R);
t[cnt*-] = L, t[cnt*] = R;
}
std::sort(mp+, mp+cnt+);
std::sort(t+, t+*cnt+);
for (int i=; i<=cnt; i++)
{
int x = std::lower_bound(t+, t+*cnt+, mp[i].first)-t;
int y = std::lower_bound(t+, t+*cnt+, mp[i].second)-t;
ans += query(y)-query(x-);
add(y);
}
printf("%lld\n",ans);
return ;
}

END

【树状数组 离散化】bzoj1573: [Usaco2009 Open]牛绣花cowemb的更多相关文章

  1. BZOJ1573: [Usaco2009 Open]牛绣花cowemb

    求半径d<=50000的圆(不含边界)内n<=50000条直线有多少交点,给直线的解析式. 一开始就想,如果能求出直线交点与原点距离<d的条件,那么从中不重复地筛选即可.然而两个kx ...

  2. hdu4605 树状数组+离散化+dfs

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  4. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

  5. 2019牛客暑期多校训练营(第七场)E-Find the median(思维+树状数组+离散化+二分)

    >传送门< 题意:给n个操作,每次和 (1e9范围内)即往数组里面插所有 的所有数,求每次操作后的中位数思路:区间离散化然后二分答案,因为小于中位数的数字恰好有个,这显然具有单调性.那么问 ...

  6. 牛客网多校第5场 H subseq 【树状数组+离散化】

    题目:戳这里 学习博客:戳这里 题意:给n个数为a1~an,找到字典序第k小的序列,输出该序列所有数所在位置. 解题思路:先把所有序列预处理出来,方法是设一个数组为dp,dp[i]表示以i为开头的序列 ...

  7. 牛客网多校第5场 I vcd 【树状数组+离散化处理】【非原创】

    题目:戳这里 学习博客:戳这里 作者:阿狸是狐狸啦 n个点,一个点集S是好的,当且仅当对于他的每个子集T,存在一个右边无限延长的矩形,使的这个矩形包含了T,但是和S-T没有交集. 求有多少个这种集合. ...

  8. BZOJ-1227 虔诚的墓主人 树状数组+离散化+组合数学

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec Memory Limit: 259 MB Submit: 914 Solved: 431 [Submit][Statu ...

  9. POJ 2299 树状数组+离散化求逆序对

    给出一个序列 相邻的两个数可以进行交换 问最少交换多少次可以让他变成递增序列 每个数都是独一无二的 其实就是问冒泡往后 最多多少次 但是按普通冒泡记录次数一定会超时 冒泡记录次数的本质是每个数的逆序数 ...

随机推荐

  1. IT兄弟连 JavaWeb教程 JSP内置对象经典面试题

    1.请说明cookie.request.session.application的作用域和声明周期? 并说明它们适用与什么场景? request的生命周期是一次请求.可以用于JSP表单提交数据. ses ...

  2. 覆盖equals方法时请遵守通用约定

    覆盖equals方法时请遵守通用约定   覆盖equals方法看起来很简单,但是有许多覆盖方式会导致错误,并且后果很严重.最容易避免这种类问题的方法就是不覆盖equals方法,在这种情况下,类的每个实 ...

  3. 解决DDOS攻击生产案例

    根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP. 当然各个公司的IP并发数各有不同,上面只是举例说明. 因为我的Nginx的WEB日 ...

  4. python数据结构转换&格式化

    列表,元组和字符串python中有三个内建函数:,他们之间的互相转换使用三个函数,str(),tuple()和list(),具体示例如下所示 >>> s = "xxxxx& ...

  5. C# 面向对象之面向接口

    接口的定义 与类不同的是接口用interface关键字 (1)接口中所有成员不能添加任何修饰符,默认为public,如果显示指定修饰符将会出现编译错误; (2)接口中不能包含字段.运算符重载.实例构造 ...

  6. DISTINCT 去重---SQL

    SQL SELECT DISTINCT 语句 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值. DISTINCT 关键词用于返回唯一不同的值. SQL SELE ...

  7. Tinghua Data Mining

    Learning Resources 书籍: 期刊: 业界先驱: 开阔视野,掌握业界最新动态. 工具: 数据挖掘是很多学科的综合体: 甭管叫什么名字,归根到底都是数据挖掘: Comprehensive ...

  8. 【aspnetcore】在过滤器(Filter)中使用注入服务(ServiceFilter|TypeFilter)

    在MVC中,AOP是很常用的功能,我们经常会使用如 ActionFilter,IAuthorizeFilter 等描述对Controller和Action进行约束和扩展,一般做法如下: public ...

  9. python学习之字符编码

    字符串涉及到编码:ascii gbk gb2312 unicode uft-8 对于英文字符ASCII(可以看成utf-8的子集)就可以了,中文用gbk/gb2312; unicode:世界统一(兼容 ...

  10. functools模块中的函数

    Python自带的functools模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数.换言之,就是能使用该模块对可调用对象进行处理.functools模块函数概览functools.cm ...