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

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

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

分析:

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

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

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define maxn 200050
typedef 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;
        mapmp;
        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;
    }
}





 



你可能感兴趣的:(离散化)