解方程题!

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. Quantitative proteomic analysis of small and large extracellular vesicles (EVs) reveals enrichment of adhesion proteins in small EVs (文献分享一组-柯酩)

    文献名:Quantitative proteomic analysis of small and large extracellular vesicles (EVs) reveals enrichme ...

  2. bzoj1458士兵占领

    传送门 和上一题差不多,每行和每列分别看做一个点,障碍点坐标的行和列就不建边,再按照有源汇上下界建图就好了,唯一的区别就是这个题求的是最小流 这个题的数据好水呢,建错图也能A呢 #include< ...

  3. iOS开发:创建推送开发证书和生产证书,以及往极光推送官网上传证书的步骤方法

    在极光官网上面上传应用的极光推送证书的实质其实就是上传导出的p12文件,在极光推送应用管理里面,需要上传两个p12文件,一个是生产证书,一个是开发证书 ,缺一不可,具体如下所示: 在开发者账号里面创建 ...

  4. [題解] luogu p1220 關路燈

    區間dp 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. ...

  5. scrapy框架中选择器的用法

    scrapy框架中选择器的用法 Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分Xpath是专门在XML文件中 ...

  6. morhpia(4)-更新

    更新由2部分组成:一个查询和一组更新操作符.本例是跟所有薪水小于等于2000的员工涨工资500. @Test public void update() throws Exception { //第一步 ...

  7. jQuery插件pagination.js源码解读

    pagination的github地址:https://github.com/gbirke/jquery_pagination 公司用的是1.2的版本,所以我就读1.2的了. jQuery.fn.pa ...

  8. 1049 - Deg-route

    http://www.ifrog.cc/acm/problem/1049 这些数学题我一般都是找规律的.. 先暴力模拟了前面的那些,然后发现(x, y) = (x, y - 1) + (x - 1, ...

  9. 17115 ooxx numbers 交表

    17115 ooxx numbers 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description a number ...

  10. odoo filter 日期

    <!--日期--> <filter name="before_twodays" string="前天" domain="[('dat ...