题目大意:给你与坐标轴平行的线段,问相交点有多少。
我们将与x轴平行的线段分成两个点,左端点与右端点,与y坐标平行的线段取它的x坐标作为一个点,排序。那么一遍扫过去,遇到左端点,对应的y坐标++,遇到右端点对应的y坐标--,遇到第三种点,就是统计当前这个点对应y1,y2坐标之间出现过多少点。支持单点修改,区间求和,线段树树状数组都可以高效求解。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85#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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复