zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    15.Mysql之undo 日志浅谈02
    14.Mysql之redo log -checkpoint浅谈01
    13. Mysql之二进制日志(binlog)
    [C]使用argv的5种方法
    [Python]sys.stdin.readline(), sys.stdout.write(), sys.stdin.write()
    temporadas[i][2]三种等价形式
    time.h中time(NULL),stdlib.h中srand(), rand()
    strstr函数的使用
    [C]toupper, tolower
    [Python]List Comprehension
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13532782.html
Copyright © 2011-2022 走看看