HDU 3511 圆的扫描线

题意:

给了n(n<50000)圆的圆心坐标和半径,任意两个圆不会相切或者相交,也就是说只存在内含和相离两种关系,问最深的那个圆被嵌套了多少次。

 

题解:

抄的别人的。。然后自己还不会nlogn的实现。。

后来看别人代码,发现,set用的太神了!

比较函数中有一个变量,但是这个变量的改变并不会影响set的形态!所以不会出问题!

http://hi.baidu.com/bobo__bai/item/17f7b28bd5994a5d850fab39

 

View Code
  1 #include <iostream>

  2 #include <cstdio>

  3 #include <cstdlib>

  4 #include <algorithm>

  5 #include <cstring>

  6 #include <set>

  7 #include <cmath>

  8 

  9 #define N 222222

 10 

 11 using namespace std;

 12 

 13 struct C

 14 {

 15     int x,y,r,w;

 16 }c[N];

 17 

 18 struct E

 19 {

 20     int x,id,fg;

 21 }li[N];

 22 

 23 int n,nx,cnt;

 24 

 25 inline double gety(int id,int fg)

 26 {

 27     double dy=sqrt(c[id].r*1.0*c[id].r-(nx-c[id].x)*1.0*(nx-c[id].x));//爆int!! 

 28     if(fg==1) return dy+c[id].y;

 29     return -dy+c[id].y;

 30 }

 31 

 32 struct SL

 33 {

 34     int fg,id;

 35     bool operator<(const SL a) const

 36     {

 37         double y1=gety(id,fg);

 38         double y2=gety(a.id,a.fg);

 39         if(y1==y2) return fg>a.fg;

 40         else return y1>y2;

 41     }

 42 };

 43 

 44 set<SL> s;

 45 set<SL>::iterator pre,suc,it;

 46 

 47 inline void add(C &c,int id)

 48 {

 49     li[++cnt].id=id; li[cnt].x=c.x-c.r; li[cnt].fg=1;

 50     li[++cnt].id=id; li[cnt].x=c.x+c.r; li[cnt].fg=-1;

 51 }

 52 

 53 inline bool cmp(const E &a,const E &b)

 54 {

 55     if(a.x==b.x) return c[a.id].y>c[b.id].y;

 56     return a.x<b.x;

 57 }

 58 

 59 inline void read()

 60 {

 61     cnt=0;

 62     for(int i=1;i<=n;i++)

 63     {

 64         scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r);

 65         c[i].w=0;

 66         add(c[i],i);

 67     }

 68     sort(li+1,li+1+cnt,cmp);

 69 }

 70 

 71 inline void go()

 72 {

 73     s.clear();

 74     SL node;

 75     for(int i=1;i<=cnt;i++)

 76     {

 77         nx=li[i].x;

 78         if(li[i].fg==1)

 79         {

 80             node.id=li[i].id; node.fg=1;

 81             it=s.insert(node).first;//.first返回插入位置,.second返回是否插入成功 

 82             suc=pre=it; suc++;

 83             if(it==s.begin()||suc==s.end()) c[it->id].w=1;

 84             else

 85             {

 86                 pre--;

 87                 if(pre->id==suc->id) c[it->id].w=c[pre->id].w+1;

 88                 else c[it->id].w=max(c[pre->id].w,c[suc->id].w);

 89             }

 90             node.fg=-1; s.insert(node);

 91         }

 92         else

 93         {

 94             node.id=li[i].id; node.fg=1; s.erase(node);

 95             node.fg=-1; s.erase(node);

 96         }

 97     }

 98     int ans=0;

 99     for(int i=1;i<=n;i++) ans=max(ans,c[i].w);

100     printf("%d\n",ans);

101 }

102 

103 int main()

104 {

105     while(scanf("%d",&n)!=EOF) read(),go();

106     return 0;

107 }

 

 

你可能感兴趣的:(HDU)