HDU 5862 Counting Intersections

题目:Counting Intersections

链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5862

题意:给出n 条平行于坐标轴的线段,问这些线段有多少交点(题目保证没有两条线段共享一个端点、保证没有重叠、保证线段长度大于0)n范围10万

思路:

  将n 条线段2n 个点按x 排序,然后当遇到一个横向的左端点时,对应的y++,遇到右端点,y--,遇到竖线,交点数目加上 下端点到上端点 之间的y 的和。离散化加树状数组可做。要注意细节,排序的优先级要注意。我的做法是直接按x 排序,然后处理的时候相同x 的一起处理(分3 次,先把要加的全部加上,然后有询问就询问,最后才减,不这样的话,T形的就比较麻烦了)

AC代码:

  1 #include<stdio.h>
  2 #include<map>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 #define LL long long
  7 struct Point
  8 {
  9   int x,y;
 10   int yy;
 11   bool left;
 12   bool type;
 13 };
 14 Point v[200020];
 15 int vo;
 16 bool cmp1(Point x,Point y)
 17 {
 18   return x.x<y.x;
 19 }
 20 bool cmp2(Point x,Point y)
 21 {
 22   return x.y<y.y;
 23 }
 24 int c[200020];
 25 int Lowbit(int x)
 26 {
 27   return x&(-x);
 28 }
 29 int getsum(int pos)
 30 {
 31   int sum=0;
 32   while(pos>0)
 33   {
 34     sum+=c[pos];
 35     pos-=Lowbit(pos);
 36   }
 37   return sum;
 38 }
 39 void update(int pos,int num,int n)
 40 {
 41    while(pos<=n)
 42    {
 43      c[pos]+=num;
 44      pos+=Lowbit(pos);
 45    }
 46 }
 47 map<int,int> mp;
 48 int main()
 49 {
 50   int t,n;
 51   scanf("%d",&t);
 52   while(t--)
 53   {
 54     mp.clear();
 55     scanf("%d",&n);
 56     vo=0;
 57     for(int i=0;i<n;i++)
 58     {
 59       scanf("%d%d%d%d",&v[vo].x,&v[vo].y,&v[vo+1].x,&v[vo+1].y);
 60       vo+=2;
 61       v[vo-2].type=v[vo-1].type= v[vo-2].x==v[vo-1].x;  //ÊúµÄÊÇ 1
 62       if(v[vo-2].type==1 && v[vo-2].y>v[vo-1].y) swap(v[vo-2],v[vo-1]);
 63 
 64       else if(v[vo-2].type==0 && v[vo-2].x>v[vo-1].x) swap(v[vo-2],v[vo-1]);
 65       v[vo-2].left=1 , v[vo-1].left=0;
 66       v[vo-2].yy=v[vo-1].y;
 67     }
 68     sort(v,v+vo,cmp2);
 69     int y=1;
 70     for(int i=1;i<vo;i++)
 71     {
 72       if( v[i].y==v[i-1].y ) mp[v[i-1].y]=y,v[i-1].y=y;
 73       else mp[v[i-1].y]=y,v[i-1].y=y++;
 74     }
 75     mp[v[vo-1].y]=y;
 76     v[vo-1].y=y;
 77     sort(v,v+vo,cmp1);
 78     memset(c,0,sizeof(c));
 79     LL ans=0;
 80     int flag=-1;
 81     for(int i=0;i<vo;i++)
 82     {
 83       flag=vo-1;
 84       for(int j=i;j<vo;j++)
 85       {
 86 
 87         if(v[j].x==v[i].x && v[j].left==1 && v[j].type==0)
 88         {
 89           update(v[j].y,1,y);
 90         }
 91         else if(v[j].x!=v[i].x)
 92         {
 93           flag=j-1;
 94           break;
 95         }
 96       }
 97       for(int j=i;j<=flag;j++)
 98       {
 99         if(v[j].left==1 && v[j].type==1)
100         {
101           //printf("== %d %d %d %d %d\n",v[j].x,v[j].y,v[j].type,v[j].left,v[j].yy);
102           ans+=getsum(mp[v[j].yy])-getsum(v[j].y-1);
103         }
104       }
105       for(int j=i;j<=flag;j++)
106       {
107         if(v[j].left==0 && v[j].type==0)
108         {
109           update(v[j].y,-1,y);
110         }
111       }
112       i=flag;
113     }
114     printf("%I64d\n",ans);
115   }
116   return 0;
117 }
posted @ 2016-08-18 20:53  hchlqlz  阅读(324)  评论(0编辑  收藏  举报