hdu 5862 Counting Intersections 坐标离散化+树状数组

来源:互联网 发布:linux根目录满了 后果 编辑:程序博客网 时间:2024/05/10 02:03

题目大意:给你与坐标轴平行的线段,问相交点有多少。

我们将与x轴平行的线段分成两个点,左端点与右端点,与y坐标平行的线段取它的x坐标作为一个点,排序。那么一遍扫过去,遇到左端点,对应的y坐标++,遇到右端点对应的y坐标--,遇到第三种点,就是统计当前这个点对应y1,y2坐标之间出现过多少点。支持单点修改,区间求和,线段树树状数组都可以高效求解。

#include <iostream>#include <cstdio>#include <cstdlib>#include <map>#include <cstring>#include <algorithm>using namespace std;const int maxn=1e5+10;struct point{int x,y,yy,type;bool operator<(point t)const {if(x==t.x)return type<t.type;return x<t.x;}}a[maxn*2];int siz;int pos[maxn][4];int b[maxn*4];int len;int bit[maxn*4];int sum(int i){int ans=0;while(i>0){ans+=bit[i];i-=i&-i;}return ans;}void add(int i,int x){while(i<maxn*4){bit[i]+=x;i+=i&-i;}}int main(){int t;scanf("%d",&t);while(t--){memset(bit,0,sizeof(bit));siz=len=0;int n;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d%d%d%d",&pos[i][0],&pos[i][1],&pos[i][2],&pos[i][3]);b[len++]=pos[i][0];b[len++]=pos[i][1];b[len++]=pos[i][2];b[len++]=pos[i][3];}sort(b,b+len);len=unique(b,b+len)-b;for(int i=0;i<n;i++){for(int j=0;j<4;j++){pos[i][j]=lower_bound(b,b+len,pos[i][j])-b+1;}}for(int i=0;i<n;i++){int x1,x2,y1,y2;x1=pos[i][0];y1=pos[i][1];x2=pos[i][2];y2=pos[i][3];if(y1==y2){if(x1>x2)swap(x1,x2);a[siz++]=point{x1,y1,0,-1};a[siz++]=point{x2,y1,0,1};}else{if(y1>y2)swap(y1,y2);a[siz++]=point{x1,y1,y2,0};}}sort(a,a+siz);long long ans=0;for(int i=0;i<siz;i++){if(a[i].type==0){ans+=sum(a[i].yy)-sum(a[i].y-1);}else{add(a[i].y,-a[i].type);}}printf("%I64d\n",ans);}return 0;}


0 0
原创粉丝点击