概述
题目大意:给你与坐标轴平行的线段,问相交点有多少。
我们将与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("%I64dn",ans);
}
return 0;
}
最后
以上就是笑点低指甲油为你收集整理的hdu 5862 Counting Intersections 坐标离散化+树状数组的全部内容,希望文章能够帮你解决hdu 5862 Counting Intersections 坐标离散化+树状数组所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复