hdu5862Counting Intersections(树状数组)
来源:互联网 发布:淘宝货到付款付款方式 编辑:程序博客网 时间:2024/05/19 18:16
题目链接:
http://acm.split.hdu.edu.cn/showproblem.php?pid=5862
题目大意:
给一些与坐标轴平行的线段,问有多少个交点。题目保证线段不会有重合的端点。
范围:
n<=100000。
思路:
根据题目的要求,我们可以知道交点一定是横线和竖线产生的。我们可以假设有一条扫描线从左往右扫过去。所以我们对于横线来说,遇到一个横线的左端点,就将他的y进行++操作,遇到右端点,就进行y--操作。如果遇到竖线,就对竖线[y1,y2]区间内进行统计。这两个操作可以利用树状数组维护完成。
为了保证上述操作的正确性,我们需要将坐标按x轴从小到大进行排序。注意当竖线和横线端点在同一个x的位置时,要保证左端点先加上去,然后统计,最后再将右端点减去。
这里我们可以利用一个flag标记,将左端点置为1,竖线置为0,右端点置为-1。
代码:
#include<stdio.h>#include<string.h>#include<algorithm>#define ll __int64using namespace std;struct node{ int x,y,idx,flag,ff;}p[200005];int n,m,a[200005];ll d[200005];pair<int,int>pp[200005];bool cmp(node a,node b){ if(a.x==b.x){ return a.flag>b.flag; } return a.x<b.x;}int lowbit(int x){ return x&(-x);}void update(int x,int z,int n){ while(x<=n){ d[x]+=z; x+=lowbit(x); }}ll getsum(int x){ ll ans=0; while(x){ ans+=d[x]; x-=lowbit(x); } return ans;}int main(){ int i,j,x1,y1,x2,y2; int T; scanf("%d",&T); while(T--){ memset(a,0,sizeof(a)); memset(d,0,sizeof(d)); scanf("%d",&n); int tt=0; for(i=1;i<=n;i++){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1>x2){ int tmp=x1; x1=x2; x2=tmp; tmp=y1; y1=y2; y2=tmp; } if(y1>y2){ int tmp=x1; x1=x2; x2=tmp; tmp=y1; y1=y2; y2=tmp; } p[(i-1)*2+1].x=x1; p[(i-1)*2+1].y=y1; p[(i-1)*2+2].x=x2; p[(i-1)*2+2].y=y2; p[(i-1)*2+1].ff=p[(i-1)*2+1].ff=0; if(x1==x2) { p[(i-1)*2+1].flag=p[(i-1)*2+2].flag=0; p[(i-1)*2+1].ff=1; p[(i-1)*2+2].ff=0; } else if(y1==y2) { p[(i-1)*2+1].flag=1; p[(i-1)*2+2].flag=-1; } a[++tt]=p[(i-1)*2+1].y; a[++tt]=p[(i-1)*2+2].y; } sort(a+1,a+1+tt); int xx=0; int siz=unique(a+1,a+1+tt)-a-1; for(i=1;i<=n;i++){ p[2*i-1].y=lower_bound(a+1,a+1+siz,p[2*i-1].y)-a; p[2*i].y=lower_bound(a+1,a+1+siz,p[2*i].y)-a; if(p[2*i-1].x==p[2*i].x){ pp[++xx]=make_pair(p[2*i-1].y,p[2*i].y); p[2*i-1].ff=xx; } } sort(p+1,p+1+2*n,cmp); ll ans=0; for(i=1;i<=2*n;i++){ if(p[i].flag!=0){ update(p[i].y,p[i].flag,2*n); } else { if(p[i].ff){ int t=p[i].ff; ans+=getsum(pp[t].second)-getsum(pp[t].first-1); } } } printf("%I64d\n",ans); }}/*240 0 4 04 0 4 24 -1 4 14 2 5 230 0 2 02 1 2 22 0 2 2*/
0 0
- hdu5862Counting Intersections(树状数组)
- hdu5862Counting Intersections 扫描线+线段树
- HDU 5862 Counting Intersections(树状数组)
- hdu 5682 Counting Intersections 离散化+树状数组
- HDU 5862Counting Intersections (思维+树状数组)
- HDU 5862 Counting Intersections (扫描线+树状数组)
- hdu 5862 Counting Intersections 坐标离散化+树状数组
- hdu 5862 Counting Intersections 【线段树/树状数组+离散化】
- HDU 5862 Counting Intersections(离散化+树状数组)
- hdu 5862 Counting Intersections 扫描线+树状数组
- HDU-5862-Counting Intersections(树状数组+离散化+扫描线)
- HDU 5862 Counting Intersections(树状数组+扫描线+离散化)
- HDU 5862 Counting Intersections(树状数组+离散化+扫描线)
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- shell,console,terminal / DOS、CMD的区别
- CSS伪类伪元素详解
- vim配置
- 《背包九讲》带你玩转背包问题!
- log4j出现log4j.dtd找不到的情况
- hdu5862Counting Intersections(树状数组)
- Eclipse缺少Jar包解决办法
- 嵌入式linux启动过程详解
- Spring是如何管理配置文件中大量的对象的?对一个serviceImpl,是单个还是多个?----待补充
- Leetcode 215. Kth Largest Element in an Array (Medium) (cpp)
- Python中join函数和os.path.join用法
- C语言中结构体指针的定义和引用
- Unity游戏选/创建角色界面中 职业能力图六角形
- 无界面浏览器phantomJS