Problem Counting Intersections
题目大意
给定n条水平或竖直的线段,统计所有线段的交点个数。 (n<=100000)
解题分析
首先将线段离散化。
然后将所有线段按照横坐标的顺序,按照先插入再查找再删除的顺序进行操作。
对于横线 如果是左端点,则将其纵坐标加1,右端点则减1,对于竖线直接求和就行了。
参考程序
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <string> 8 #include <vector> 9 #include <cstdio> 10 #include <cstdlib> 11 #include <cstring> 12 #include <cassert> 13 #include <iostream> 14 #include <algorithm> 15 #pragma comment(linker,"/STACK:102400000,102400000") 16 using namespace std; 17 18 #define N 100008 19 #define M 50008 20 #define LL long long 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 #define clr(x,v) memset(x,v,sizeof(x)); 24 #define rep(x,y,z) for (int x=y;x<=z;x++) 25 #define repd(x,y,z) for (int x=y;x>=z;x--) 26 const int mo = 1000000007; 27 const int inf = 0x3f3f3f3f; 28 const int INF = 2000000000; 29 /**************************************************************************/ 30 struct line{ 31 int x,y,z; 32 line(int x=0,int y=0,int z=0):x(x),y(y),z(z){} 33 bool operator <(const line b) const{ 34 return x<b.x || x==b.x && z<b.z; 35 } 36 }a[N],b[N],c[N*2]; 37 38 int val[N*4],cnt; 39 40 int id(int x){ 41 return lower_bound(val+1,val+cnt+1,x)-val; 42 } 43 44 struct Binary_Indexed_Tree{ 45 int a[N*5]; 46 void clear(){ 47 clr(a,0); 48 } 49 void insert(int x,int val){ 50 for (int i=x;i<=N<<2;i+=i & (-i)) 51 a[i]+=val; 52 } 53 int sigma(int x){ 54 int res=0; 55 for (int i=x;i>0;i-=i & (-i)) 56 res+=a[i]; 57 return res; 58 } 59 int query(int x,int y){ 60 return sigma(y)-sigma(x-1); 61 } 62 }T; 63 64 int main(){ 65 int testcase; 66 scanf("%d",&testcase); 67 while (testcase--){ 68 int n,na=0,nb=0,nc=0; 69 cnt=0; 70 scanf("%d",&n); 71 rep(i,1,n){ 72 int x1,y1,x2,y2; 73 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 74 val[++cnt]=x1; 75 val[++cnt]=y1; 76 val[++cnt]=x2; 77 val[++cnt]=y2; 78 if (x1==x2){ 79 if (y1>y2) swap(y1,y2); 80 b[++nb]=line(x1,y1,y2); 81 } 82 if (y1==y2){ 83 if (x1>x2) swap(x1,x2); 84 a[++na]=line(y1,x1,x2); 85 } 86 } 87 sort(val+1,val+cnt+1); 88 cnt=unique(val+1,val+cnt+1)-val-1; 89 rep(i,1,na){ 90 a[i].x=id(a[i].x); 91 a[i].y=id(a[i].y); 92 a[i].z=id(a[i].z); 93 c[++nc]=line(a[i].y,i,1); 94 c[++nc]=line(a[i].z,i,3); 95 } 96 rep(i,1,nb){ 97 b[i].x=id(b[i].x); 98 b[i].y=id(b[i].y); 99 b[i].z=id(b[i].z); 100 c[++nc]=line(b[i].x,i,2); 101 } 102 sort(c+1,c+nc+1); 103 T.clear(); 104 LL ans=0; 105 rep(i,1,nc){ 106 if (c[i].z==1){ 107 T.insert(a[c[i].y].x,1); 108 } 109 if (c[i].z==2){ 110 ans+=T.query(b[c[i].y].y,b[c[i].y].z); 111 } 112 if (c[i].z==3){ 113 T.insert(a[c[i].y].x,-1); 114 } 115 } 116 printf("%lld\n",ans ); 117 } 118 }