zoukankan      html  css  js  c++  java
  • BZOJ1573: [Usaco2009 Open]牛绣花cowemb

    求半径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。也就是,把原来一条直线看成两个点,两个点按极角序编号,两个点间的弧的交拉直成线段交,求这些线段有多少对交,就变成很裸的扫描线。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 #include<stdlib.h>
      5 #include<math.h>
      6 //#include<iostream>
      7 using namespace std;
      8  
      9 int n,d;
     10 #define maxn 100011
     11 const double eps=1e-10,inf=1e15;
     12 struct Line
     13 {
     14     double k,b;
     15 }a[maxn];
     16 struct Point
     17 {
     18     double x,y,t;int k,id;
     19     bool operator < (const Point &b) const
     20     {return k<b.k || (k==b.k && t>b.t);}
     21     bool operator == (const Point &b) const
     22     {return fabs(x-b.x)<eps && fabs(y-b.y)<eps;}
     23     bool operator != (const Point &b) const {return !(*this==b);}
     24 }p[maxn];int lp=0;
     25 double x,y,z;
     26 #define LL long long
     27 void addp(double x,double y,int id)
     28 {
     29     Point &e=p[++lp];
     30     e.x=x;e.y=y;e.id=id;
     31     e.t=x?y/x:inf;
     32     if (x>=0 && y>0) e.k=1;
     33     else if (x>0 && y<=0) e.k=2;
     34     else if (x<=0 && y<0) e.k=3;
     35     else e.k=4;
     36 }
     37 void makep(int x)
     38 {
     39     if (a[x].k==inf)
     40     {
     41         if (a[x].b-d>eps || a[x].b+d<-eps) return;
     42         addp(a[x].b,sqrt(1.0*d*d-a[x].b*a[x].b),x);
     43         addp(a[x].b,-sqrt(1.0*d*d-a[x].b*a[x].b),x);
     44     }
     45     else
     46     {
     47         double u=a[x].k*a[x].k+1,v=2*a[x].k*a[x].b,w=a[x].b*a[x].b-d*d;
     48         if (v*v-4*u*w<-eps) return;
     49         double tmp=(-v+sqrt(v*v-4*u*w))/(2*u);
     50         addp(tmp,a[x].k*tmp+a[x].b,x);
     51         tmp=(-v-sqrt(v*v-4*u*w))/(2*u);
     52         addp(tmp,a[x].k*tmp+a[x].b,x);
     53     }
     54 }
     55 struct BIT
     56 {
     57     int a[maxn],n;
     58     void clear(int n) {memset(a,0,sizeof(a));this->n=n;}
     59     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
     60     int query(int x) {int ans=0;for (;x;x-=x&-x) ans+=a[x];return ans;}
     61 }t;
     62 struct seg
     63 {
     64     int l,r;
     65     bool operator < (const seg &b) const {return l<b.l;}
     66 }b[maxn];
     67 bool vis[maxn];
     68 int main()
     69 {
     70     scanf("%d%d",&n,&d);
     71     for (int i=1;i<=n;i++)
     72     {
     73         scanf("%lf%lf%lf",&x,&y,&z);
     74         a[i].k=y?-x/y:inf;
     75         a[i].b=y?-z/y:-z/x;
     76         makep(i);
     77     }
     78     sort(p+1,p+1+lp);
     79     memset(vis,0,sizeof(vis));
     80     p[lp+1].x=inf;p[lp+1].y=inf;
     81     int cnt=0,last=1;
     82     for (int i=2;i<=lp+1;i++) if (p[i]!=p[i-1])
     83     {
     84         cnt++;
     85         for (int &j=last;j<i;j++)
     86             if (vis[p[j].id]) b[p[j].id].r=cnt;
     87             else vis[p[j].id]=1,b[p[j].id].l=cnt;
     88     }
     89     for (int i=1;i<=n;i++) if (!vis[i]) b[i].l=b[i].r=0x3f3f3f3f;
     90     sort(b+1,b+1+n);
     91     LL ans=0;last=1;
     92     t.clear(cnt);
     93     for (int i=2;i<=(lp>>1)+1;i++) if (b[i].l!=b[i-1].l)
     94     {
     95         for (int j=last;j<i;j++)
     96             ans+=t.query(b[j].r-1)-t.query(b[j].l);
     97         for (int &j=last;j<i;j++)
     98             t.add(b[j].r,1);
     99     }
    100     printf("%lld
    ",ans);
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7617480.html
Copyright © 2011-2022 走看看