我是靠谱客的博主 笑点低指甲油,最近开发中收集的这篇文章主要介绍hdu 5862 Counting Intersections 坐标离散化+树状数组,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

我们将与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 坐标离散化+树状数组所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部