求半径d<=50000的圆(不含边界)内n<=50000条直线有多少交点,给直线的解析式。

一开始就想,如果能求出直线交点与原点距离<d的条件,那么从中不重复地筛选即可。然而两个kx+b联立起来加勾股定理特别丑。。

换个想法,一条线在圆上就截了两个点。把这些点做极角排序后(即从y轴正半轴的射线顺时针扫一圈,把依次遇到的点排下来)后,每条直线就可以两个点表示。设其极角排序后,序较小的那个点叫A,另一个叫B。

其实就是:对所有(Ai,Bi),求有多少j满足Aj<Ai且Ai<Bj<Bi,其中小于号是极角序比较。

这就好比:给若干线段,求有多少对线段相交而不包含。也就是对所有Li,Ri,求有多少Lj<Li并且Li<Rj<Ri。也就是,把原来一条直线看成两个点,两个点按极角序编号,两个点间的弧的交拉直成线段交,求这些线段有多少对交,就变成很裸的扫描线。

 #include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<math.h>
//#include<iostream>
using namespace std; int n,d;
#define maxn 100011
const double eps=1e-,inf=1e15;
struct Line
{
double k,b;
}a[maxn];
struct Point
{
double x,y,t;int k,id;
bool operator < (const Point &b) const
{return k<b.k || (k==b.k && t>b.t);}
bool operator == (const Point &b) const
{return fabs(x-b.x)<eps && fabs(y-b.y)<eps;}
bool operator != (const Point &b) const {return !(*this==b);}
}p[maxn];int lp=;
double x,y,z;
#define LL long long
void addp(double x,double y,int id)
{
Point &e=p[++lp];
e.x=x;e.y=y;e.id=id;
e.t=x?y/x:inf;
if (x>= && y>) e.k=;
else if (x> && y<=) e.k=;
else if (x<= && y<) e.k=;
else e.k=;
}
void makep(int x)
{
if (a[x].k==inf)
{
if (a[x].b-d>eps || a[x].b+d<-eps) return;
addp(a[x].b,sqrt(1.0*d*d-a[x].b*a[x].b),x);
addp(a[x].b,-sqrt(1.0*d*d-a[x].b*a[x].b),x);
}
else
{
double u=a[x].k*a[x].k+,v=*a[x].k*a[x].b,w=a[x].b*a[x].b-d*d;
if (v*v-*u*w<-eps) return;
double tmp=(-v+sqrt(v*v-*u*w))/(*u);
addp(tmp,a[x].k*tmp+a[x].b,x);
tmp=(-v-sqrt(v*v-*u*w))/(*u);
addp(tmp,a[x].k*tmp+a[x].b,x);
}
}
struct BIT
{
int a[maxn],n;
void clear(int n) {memset(a,,sizeof(a));this->n=n;}
void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
int query(int x) {int ans=;for (;x;x-=x&-x) ans+=a[x];return ans;}
}t;
struct seg
{
int l,r;
bool operator < (const seg &b) const {return l<b.l;}
}b[maxn];
bool vis[maxn];
int main()
{
scanf("%d%d",&n,&d);
for (int i=;i<=n;i++)
{
scanf("%lf%lf%lf",&x,&y,&z);
a[i].k=y?-x/y:inf;
a[i].b=y?-z/y:-z/x;
makep(i);
}
sort(p+,p++lp);
memset(vis,,sizeof(vis));
p[lp+].x=inf;p[lp+].y=inf;
int cnt=,last=;
for (int i=;i<=lp+;i++) if (p[i]!=p[i-])
{
cnt++;
for (int &j=last;j<i;j++)
if (vis[p[j].id]) b[p[j].id].r=cnt;
else vis[p[j].id]=,b[p[j].id].l=cnt;
}
for (int i=;i<=n;i++) if (!vis[i]) b[i].l=b[i].r=0x3f3f3f3f;
sort(b+,b++n);
LL ans=;last=;
t.clear(cnt);
for (int i=;i<=(lp>>)+;i++) if (b[i].l!=b[i-].l)
{
for (int j=last;j<i;j++)
ans+=t.query(b[j].r-)-t.query(b[j].l);
for (int &j=last;j<i;j++)
t.add(b[j].r,);
}
printf("%lld\n",ans);
return ;
}

BZOJ1573: [Usaco2009 Open]牛绣花cowemb的更多相关文章

  1. 【树状数组 离散化】bzoj1573: [Usaco2009 Open]牛绣花cowemb

    解方程题! Description Bessie学会了刺绣这种精细的工作.牛们在一片半径为d(1 <= d <= 50000)的圆形布上绣花. 它们一共绣了N (2 <= N < ...

  2. NOIP2018 - 暑期博客整理

    暑假写的一些博客复习一遍.顺便再写一遍或者以现在的角度补充一点东西. 盛暑七月 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士 比较经典的基环外向树dp.可以借鉴的 ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. BZOJ3403: [Usaco2009 Open]Cow Line 直线上的牛

    3403: [Usaco2009 Open]Cow Line 直线上的牛 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 48  Solved: 41[S ...

  5. BZOJ 3403: [Usaco2009 Open]Cow Line 直线上的牛( deque )

    直接用STL的的deque就好了... ---------------------------------------------------------------------- #include& ...

  6. 3403: [Usaco2009 Open]Cow Line 直线上的牛

    3403: [Usaco2009 Open]Cow Line 直线上的牛 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 71  Solved: 62[S ...

  7. 【BZOJ】3403: [Usaco2009 Open]Cow Line 直线上的牛(模拟)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3404 裸的双端队列.. #include <cstdio> #include <c ...

  8. B3403 [Usaco2009 Open]Cow Line 直线上的牛 deque

    deque真的秀,queue和stack...没啥用了啊.操作差不多,就是在前面加一个front||back_就行了. 题干: 题目描述 题目描述     约翰的N只奶牛(编为1到N号)正在直线上排队 ...

  9. BZOJ 3403: [Usaco2009 Open]Cow Line 直线上的牛(模拟)

    直接双端队列模拟,完了= = CODE: #include<cstdio>#include<algorithm>#include<iostream>#include ...

随机推荐

  1. AJPFX关于集合的几种变量方式

    package com.java.test; import java.util.ArrayList;import java.util.Enumeration;import java.util.Iter ...

  2. 关于对象.style currentstyle 的区别

    对象.style的方式只能获取行内写法的样式,但是外部引入的或者写在head里面的就无法获取,只能用currentstyle.

  3. Android Studio Terminal 不是内部或外部命令,也不是可运行程序或批处理文件

    1.Android Studio Terminal 命令行无效的问题 在Android Studio中自带了命令行终端Terminal,但是我们在输入命令时经常会发现:“XXX”不是内部或外部命令,也 ...

  4. 在uwp仿IOS的页面切换效果

    有时候我们需要编写一些迎合IOS用户使用习惯的uwp应用,我在这里整理一下仿IOS页面切换效果的代码. 先分析IOS的页面切换.用户使用左右滑动方式进行前进和后退,播放类似于FlipView的切换动画 ...

  5. Windows各个文件夹介绍

    windows文件介绍 总结 ├WINDOWS │ ├-system32(存放Windows的系统文件和硬件驱动程序) │ │ ├-config(用户配置信息和密码信息) │ │ │ └-system ...

  6. SEO 第七章

    SEO第七章 网站网址链接 路径优化 网站的网址路径分为相对路径和绝对路径 绝对路径:绝对路径是完整的路径,不仅可以在站内打开,去其他地方依然可以打开. 相对路径:不是一个完整的路径,这种路径只能在站 ...

  7. 云态(YunCloud)的Centos服务器修改dns教程

    DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串.通过主机名,最终 ...

  8. 前端什么是BFC

    什么是BFC? 全称块级格式化上下文?什么意思不懂.看了好多博客,基本都是抄的,真心都不是大白话.我今天来总结一下,用菜鸟级别的语言来描述. BFC 应该可以抽象成一个 独立的个体,出淤泥而不染的白莲 ...

  9. Python matlab octave 矩阵运算基础

    基础总结,分别在三种软件下,计算 求逆矩阵 矩阵转置 等运算,比较异同 例子:正规方程法求多元线性回归的最优解 θ=(XTX)-1XTY octave: pwd()当前目录 ones() zeros( ...

  10. 尺取法 || emmmm

    给定两个上升的数组,一个数组任取一个数,求两个数差的min 尺取法emm 也不知道对不对 #include <stdio.h> #include <stdlib.h> #def ...