树状数组+离散化(hdu 5862)
来源:互联网 发布:河北网络电视台 - 百度 编辑:程序博客网 时间:2024/06/06 14:11
题目:hdu 5862
题意:给定几个线段,求有多少个线段的交点,输入解释:第一行表示测试数据,第二行表示有多少条线段,第三行开始是每个线段的两点坐标
题解:树状数组+离散化(Y坐标太大,要压缩存储空间,采用离散化),先用map对y坐标进行离散化,再将与x轴平行的线段拆成两个点,一个是记录起点x坐标,一个记录末点x坐标+1(这样就可保证末点相交被记录进去,方便),与y轴平行的只要记录x坐标和两个y坐标即可,当成一个点,在将所有点以x坐标从小到大进行排列,排除掉了x坐标,就只要考虑y坐标即可,这样树状数组就可进行维护了,在树状数组中以Y坐标为高度,凡是高度在此中间的一定有交点,当然也要有个变量记录该点对应的线段是从与x轴平行的提取出来的还是y轴,具体见下代码
代码:
include<iostream>#include<cstdio>#include<cstring>#include<map>#include<algorithm>#include<string>#define MAX 100050using namespace std;typedef struct{ int kind,x,y,y2;}Segment;Segment s[MAX*2];int Y[MAX*2];int c[MAX*2];int num;int ynum;int mxan;map<int,int> mp;void init(){ num=0;memset(c,0,sizeof(c));ynum=0;mp.clear();mxan=MAX*2;}void addSegment(int kind,int x,int y,int y2){ s[num].kind=kind;s[num].x=x;s[num].y=y;s[num].y2=y2; num++;}bool compareY(int y1,int y2){ return y1<y2;}bool compareX(Segment z1,Segment z2)//以x坐标进行排序,当坐标相等时,要保证从平行x轴提取的点先进行考虑{ if(z1.x==z2.x) { return z1.kind<z2.kind; } else { return z1.x<z2.x; }}int lowbit(int x){ return x&(-x);}void add(int i,int v){ while(i<=mxan) { c[i]+=v; i+=lowbit(i); }}int sum(int i){ int ans=0; while(i>0) { ans+=c[i]; i-=lowbit(i); } return ans;}int main(){ int t; scanf("%d",&t); while(t--) { int n; init(); scanf("%d",&n); for(int i=0;i<n;i++) { int x,y,x1,y1; scanf("%d %d %d %d",&x,&y,&x1,&y1); if(x==x1) { if(y1>y) swap(y,y1); addSegment(1,x,y,y1); Y[ynum++]=y; Y[ynum++]=y1; } else { if(x>x1) swap(x,x1); addSegment(0,x,y,1); addSegment(0,x1+1,y,-1); Y[ynum++]=y; } } sort(Y,Y+ynum,compareY); int count1=1; for(int i=0;i<ynum;i++)//离散化 { if(!mp[Y[i]]) {mp[Y[i]]=count1++;} } mxan=count1+1; sort(s,s+num,compareX); long long sum2=0; for(int i=0;i<num;i++) { if(s[i].kind==0) { add(mp[s[i].y],s[i].y2); } else { sum2+=sum(mp[s[i].y])-sum(mp[s[i].y2]-1); } } printf("%lld\n",sum2); } return 0;}
0 0
- 树状数组+离散化(hdu 5862)
- hdu 5862(离散化+树状数组)
- hdu 5877(树状数组+离散化)
- HDU 5862 Counting Intersections(离散化+树状数组)
- hdu 5862 树状数组 + 扫描线 + 离散化
- hdu 5862 Counting Intersections 坐标离散化+树状数组
- hdu 5862 Counting Intersections 【线段树/树状数组+离散化】
- hdu 3607 Traversal(树状数组+离散化)
- hdu 3743 Frosh Week (树状数组的离散化)
- hdu - 4911 - Inversion(离散化+树状数组)
- HDU - 3743 Frosh Week(树状数组+离散化)
- hdu 5372 Segment Game (树状数组+离散化)
- HDU-5792-World is Exploding(树状数组+离散化)
- hdu 3333(树状数组,离线,离散化)
- HDU 5877 dfs+离散化+树状数组(树上维护)
- HDU 5877(Problem 1010) (DFS+树状数组+离散化)
- hdu 5877 Weak Pair(树状数组 + dfs + 离散化)
- 树状数组,离散化,突破口(Segment Game,HDU 5372)
- 【SSH】之 Struts
- 基本查找算法
- Ble4.0 APP开发总结
- 数据库MySQL-----------多表连接
- Git 常用命令速查
- 树状数组+离散化(hdu 5862)
- 把Android library分享到jCenter的方法
- docker学习7--宿主机和容器时间不一致问题
- dede使用phpMailer类配置微软邮箱发送邮件
- iOS上架流程
- 06使用CSS设置图片样式
- ubuntu小知识集锦
- 字符串
- iOS NSMutableAttributedString 实现富文本