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
  • 相关阅读:
    mysql支持跨表delete删除多表记录
    三种循环的流程图画法总结
    巧用svn create patch(打补丁)方案解决定制版需求
    svn branch and merge(svn切换分支和合并)详解
    visualvm
    Java -verbose[:class|gc|jni] 转 ----JAVA源码分析
    BootstrapClassloader ExtClassloader AppClassloader
    LINUX 源码+内核所有参数说明
    SDN
    人工智能之数学基础
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7617480.html
Copyright © 2011-2022 走看看