hdu 5862(离散化+树状数组)

来源:互联网 发布:中维网络监控 编辑:程序博客网 时间:2024/06/11 03:02

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5862

题意:给你n条平行x轴或y轴的直线,求直线之间交点的个数

分析:

首先按照x轴排序,这样扫描竖线时就不用考虑 左端点在竖线右边的横线

因为结果只依赖于左端点在竖线左边的横线,所以用树状数组保存及更新(当有左端点进入时+1,右端点-1)

#include <cstdio>#include <iostream>#include <map>#include <algorithm>#include <cstring>using namespace std;#define maxn 200050typedef long long int LL;int T , n;struct Node//type 0 代表横向,1代表竖线{    int x,y,y1,type;//当为横线时 y1 = 1 代表左端点 ,y1 = -1 代表右端点    bool operator < (const Node & R)const{        return (x == R.x ? type < R.type : x < R.x);    }}node[maxn];int ncnt;int yi[maxn];int ycnt;int Maxn;int bi[maxn];void add(int n,int add){    for(int i = n ; i <= Maxn ; i += i&(-i))        bi[i] += add;}LL getNum(int n){    LL res = 0;    for(int i = n ; i >= 1; i -= i&(-i))        res += bi[i];    return res;}void init(){    ncnt = ycnt = 0;    memset(bi,0,sizeof(bi));}int main(){    cin >> T;    while( T-- )    {        init();        cin >> n;        for(int i = 0 ; i < n ; ++i)        {            int x1,y1,x2,y2;            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);            if( x1 == x2 )            {                if( y1 > y2 )swap(y1,y2);                yi[ycnt++] = y1;                yi[ycnt++] = y2;                node[ncnt++] = {x1,y1,y2,1};            }            else            {                if( x1 > x2 )swap(x1,x2);                yi[ycnt++] = y1;                node[ncnt++] = {x1,y1,1,0};                node[ncnt++] = {x2+1,y2,-1,0};//因为在x2点时 还可以相交            }        }        sort(yi,yi+ycnt);        int acl = 0;        map<int,int>mp;        for (int i = 0; i < ycnt; i++){            if (!mp[yi[i]]) mp[yi[i]] = ++acl;        }        Maxn = acl;        sort(node,node+ncnt);        LL ans = 0 ;        for(int i = 0 ; i < ncnt ; ++i)        {            Node &e = node[i];            if( e.type )//竖线            {                ans += getNum(mp[e.y1]) - getNum(mp[e.y]-1);            }            else            {                add( mp[e.y] , e.y1 );            }        }        cout << ans << endl;    }}





 



原创粉丝点击