多校训练10&&HDU5862 Counting Intersections
来源:互联网 发布:华东医院数据库 编辑:程序博客网 时间:2024/05/22 02:21
【题意】真水的题。。不知道我们队干了什么,卡在A题这个水题几个小时,太悲哀了。
【解题方法】这不好说,去偷一份我同学的解题方法吧,思路大概都是这样,扫描线的基础题了,BIT维护信息,扫描线扫过去就完了。
因为题目已经说明所有的线段都是平行于坐标轴的
那么,线段无外乎两种:①平行于x轴;②平行于y轴
那交点必定只有竖向与横向的线段才会产生
另外,此题数据规模显然是不允许我们进行O(n^2)的暴力求解
那我们可以将横向的线段与竖向线段分开处理
对于横向的线段,我们只保留端点
再按x从小到大排序,x相等的情况下,左端点优先于右端点
而竖向的线段同样按x从小到大排序,但是不拆分成两个端点,而是保留整条线段
然后枚举竖向线段,将小于该竖向线段横坐标的所有点进行处理
若点为左端点,则在其对应的值处的树状数组做+1操作,若为右端点,则做-1操作
这保证了对于第i条竖向线段,当前树状数组中记录了横坐标横跨该竖向线段的线段数量
【AC 代码】
#include <bits/stdc++.h>using namespace std;const int maxn = 500010;typedef long long LL;struct bit{ LL c[maxn];int n; void init(int _n){ memset(c,0,sizeof(c)); n=_n; } void add(int i,int v){ while(i<=n){ c[i]+=v; i+=i&-i; } } int getans(int i){ int ans=0; while(i>0){ ans+=c[i]; i-=i&-i; } return ans; }}BIT;struct node1{ int x1,y1,x2,y2;}seg[maxn],q[maxn];struct node2{ int x,y,type;}p[maxn];bool cmp1(node2 a,node2 b){ if(a.x!=b.x) return a.x<b.x; return a.type<b.type;}bool cmp2(node1 a,node1 b){ return a.x1<b.x1;}vector<int>xs;int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); LL ans=0; BIT.init(maxn); xs.clear(); for(int i=1; i<=n; i++){ scanf("%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2); if(q[i].x1>q[i].x2||q[i].y1>q[i].y2){ swap(q[i].x1,q[i].x2); swap(q[i].y1,q[i].y2); } xs.push_back(q[i].x1); xs.push_back(q[i].y1); xs.push_back(q[i].x2); xs.push_back(q[i].y2); } sort(xs.begin(),xs.end()); xs.resize(unique(xs.begin(),xs.end())-xs.begin()); int k1=0,k2=0; for(int i=1; i<=n; i++){ int x1=lower_bound(xs.begin(),xs.end(),q[i].x1)-xs.begin()+1; int y1=lower_bound(xs.begin(),xs.end(),q[i].y1)-xs.begin()+1; int x2=lower_bound(xs.begin(),xs.end(),q[i].x2)-xs.begin()+1; int y2=lower_bound(xs.begin(),xs.end(),q[i].y2)-xs.begin()+1; if(y1==y2){ p[++k1].x=x1,p[k1].y=y1,p[k1].type=0; p[++k1].x=x2,p[k1].y=y2,p[k1].type=1; }else{ seg[++k2]=node1{x1,y1,x2,y2}; } } sort(p+1,p+k1+1,cmp1); sort(seg+1,seg+k2+1,cmp2); //扫描线段 for(int i=1,j=1; i<=k2; i++){ while(j<=k1&&(p[j].x<seg[i].x1||(p[j].x==seg[i].x1&&p[j].type==0))){ if(p[j].type==0) BIT.add(p[j].y,1); else BIT.add(p[j].y,-1); j++; } ans+=BIT.getans(seg[i].y2)-BIT.getans(seg[i].y1-1); } printf("%I64d\n",ans); } return 0;}
0 0
- 多校训练10&&HDU5862 Counting Intersections
- 2016多校训练Contest10: 1006 Counting Intersections hdu5862
- hdu5862 Counting Intersections
- HDU5862-Counting Intersections
- HDU-2017 多校训练赛4-1003-Counting Divisors
- 2017 多校训练第四场 HDU 6069 Counting Divisors
- 2017多校训练Contest4: 1003 Counting Divisors hdu6069
- Counting Intersections
- 多校训练
- HDU 6069-Counting Divisors(多校训练第四场->区间质因数个数)
- HDU 5862 Counting Intersections
- HDU - 5862 Counting Intersections
- HDU 5862 Counting Intersections
- HDU 5862 Counting Intersections
- Counting Intersections HDU
- Contest - 多校训练(三
- Contest - 多校训练(三
- ZZULIOJ 多校训练三
- HDU 4451 Dressing(计数)
- 设置函数环境——setfenv
- 51nod 1050 循环数组最大子段和
- 数据结构:单链表 C++实现
- 首届英才在线编程大赛-编程题回顾-java实现
- 多校训练10&&HDU5862 Counting Intersections
- android之数据存储2
- [Json] Java中Json相关操作
- android控件——textView使用
- hadoop中NameNode、DataNode、Secondary、NameNode、JobTracker TaskTracker介绍
- 标准W3C盒子模型和IE盒子模型CSS布局经典盒子模型
- 9. Palindrome Number
- 网易内推面经_Android开发
- hdu 5867 Water problem