HDU 5862(离散化+树状数组)

时间:2022-10-20 20:58:33

Problem Counting Intersections

题目大意

  给定n条水平或竖直的线段,统计所有线段的交点个数。 (n<=100000)

解题分析

  首先将线段离散化。

  然后将所有线段按照横坐标的顺序,按照先插入再查找再删除的顺序进行操作。

  对于横线 如果是左端点,则将其纵坐标加1,右端点则减1,对于竖线直接求和就行了。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define M 50008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/
struct line{
int x,y,z;
line(int x=,int y=,int z=):x(x),y(y),z(z){}
bool operator <(const line b) const{
return x<b.x || x==b.x && z<b.z;
}
}a[N],b[N],c[N*]; int val[N*],cnt; int id(int x){
return lower_bound(val+,val+cnt+,x)-val;
} struct Binary_Indexed_Tree{
int a[N*];
void clear(){
clr(a,);
}
void insert(int x,int val){
for (int i=x;i<=N<<;i+=i & (-i))
a[i]+=val;
}
int sigma(int x){
int res=;
for (int i=x;i>;i-=i & (-i))
res+=a[i];
return res;
}
int query(int x,int y){
return sigma(y)-sigma(x-);
}
}T; int main(){
int testcase;
scanf("%d",&testcase);
while (testcase--){
int n,na=,nb=,nc=;
cnt=;
scanf("%d",&n);
rep(i,,n){
int x1,y1,x2,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
val[++cnt]=x1;
val[++cnt]=y1;
val[++cnt]=x2;
val[++cnt]=y2;
if (x1==x2){
if (y1>y2) swap(y1,y2);
b[++nb]=line(x1,y1,y2);
}
if (y1==y2){
if (x1>x2) swap(x1,x2);
a[++na]=line(y1,x1,x2);
}
}
sort(val+,val+cnt+);
cnt=unique(val+,val+cnt+)-val-;
rep(i,,na){
a[i].x=id(a[i].x);
a[i].y=id(a[i].y);
a[i].z=id(a[i].z);
c[++nc]=line(a[i].y,i,);
c[++nc]=line(a[i].z,i,);
}
rep(i,,nb){
b[i].x=id(b[i].x);
b[i].y=id(b[i].y);
b[i].z=id(b[i].z);
c[++nc]=line(b[i].x,i,);
}
sort(c+,c+nc+);
T.clear();
LL ans=;
rep(i,,nc){
if (c[i].z==){
T.insert(a[c[i].y].x,);
}
if (c[i].z==){
ans+=T.query(b[c[i].y].y,b[c[i].y].z);
}
if (c[i].z==){
T.insert(a[c[i].y].x,-);
}
}
printf("%lld\n",ans );
}
}