hdu5862 树状数组+扫描线+离散化

hdu5862 Counting Intersections
传送门
题意
(n)条与(x)轴或者(y)轴平行的线段,计算交点的个数
(1leq nleq 100000),端点坐标的绝对值不超过(1e9)
题解
按照纵坐标从小到大扫描,竖线两个端点按照两个元素存储,横线由于只有一个纵坐标,按照一个元素存储,同时通过(id)表示是横线还是竖线的端点
树状数组统计与每一条横线相交的交点个数,扫描到竖线的下端点时,将这条竖线的横坐标对应的树状数组元素加一,表示加入,扫描到下端点时,同样的横坐标对应的树状数组元素值减一,表示删除
扫描到横线时,如果左右端点分别为(l)(r),则树状数组统计与这条横线相交的交点个数为(query(r)-query(l-1))
(ps:)由于坐标值可能较大,而点数不超过(1e5),所以横坐标离散化之后再用树状数组统计

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;

const int maxn=100010;
int T,n,ax[2*maxn],bit[2*maxn];
struct node{
    int x1,x2,y,id;
    bool operator < (const node t)const{
        if(y!=t.y) return y<t.y;
        return id>t.id;
    }
}p[2*maxn];

void change(int n,int x,int v){
    for(int i=x;i<=n;i+=lowbit(i)){
        bit[i]+=v;
    }
}

int query(int x){
    int s=0;
    for(int i=x;i>0;i-=lowbit(i)){
        s+=bit[i];
    }
    return s;
}

int main(){
    scanf("%d",&T);
    while(T--){
        memset(bit,0,sizeof(bit));
        scanf("%d",&n);
        int pi=0;
        int xi=0;
        for(int i=0;i<n;i++){
            int x1,x2,y1,y2;
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            ax[xi++]=x1;
            ax[xi++]=x2;
            if(x1>x2) swap(x1,x2);
            if(y1>y2) swap(y1,y2);
            if(x1==x2){
                p[pi].x1=x1;
                p[pi].y=y1;
                p[pi++].id=1;
                p[pi].x1=x2;
                p[pi].y=y2;
                p[pi++].id=-1; 
            }
            else{
                p[pi].x1=x1;
                p[pi].x2=x2;
                p[pi].y=y1;
                p[pi++].id=0;
            }
        }
        sort(p,p+pi);
        sort(ax,ax+xi);
        int len=unique(ax,ax+xi)-ax;
        LL ans=0;
        for(int i=0;i<pi;i++){
            if(p[i].id==0){
                int l=lower_bound(ax,ax+len,p[i].x1)-ax+1;
                int r=lower_bound(ax,ax+len,p[i].x2)-ax+1;
                ans+=query(r)-query(l-1);
            }
            else{
                int pos=lower_bound(ax,ax+len,p[i].x1)-ax+1;
                change(len,pos,p[i].id);
            }
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fxq1304/p/13532782.html