• Hdu 5862 Counting Intersections(有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点+树状数组区间求和单点跟新)


    传送门:Hdu 5862 Counting Intersections

    题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点

    分析:

    基本的操作流程是:先将所有的线段按照横树坐标x按小的优先排序,注意是所有的线段 ;(这里是将线段都去掉只保留两个端点) 然后从左到右的顺序经行扫描,遇到横的线段,如果是左端点对应的 yi 便++ , 若是右端点对应的y1便--;  遇到竖直的线段,便统计区间[y1,y2] 的数 , 看到这了是不是有点东西了呢?

    如果我是按照x排序的话,两线段若想相交,最基本的就是竖线的横坐标必须要大于等于横线的左端点,小于横线的右端点了吧,而且这条横线产生的贡献很明显就是在这横线的y坐标上呢?所有上面的流程都是依此与这个原理;(注意需要离散化哈

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2*100010;
    int t[maxn];
    struct node{
        int x,l,r,flag;
    }e[maxn];
    int C[maxn],m;
    
    bool cmp(node u,node v){
        if(u.x==v.x)
            return u.flag>v.flag;
        return u.x<v.x;
    }
    
    void add(int x,int v){
        while(x<=m) C[x]+=v,x+=(x&-x);
    }
    
    int sum(int x){
        int ret=0;
        while(x>0)
            ret+=C[x],x-=(x&-x);
        return ret;
    }
    
    int main(){
        int T,n;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            int x1,y1,x2,y2,Count=0;
            m=0;
            for(int i=1;i<=n;i++){
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                if(x1>x2)
                    swap(x1,x2);
                if(y1>y2)
                    swap(y1,y2);
                t[++m]=y1,t[++m]=y2;
                if(x1==x2)//竖直
                    e[++Count]=(node){x1,y1,y2,0};
                else{
                    e[++Count]=(node){x1,y1,y2,1};
                    e[++Count]=(node){x2,y1,y2,-1};
                }
            }
            sort(t+1,t+m+1);
            m=unique(t+1,t+m+1)-t-1;
            sort(e+1,e+Count+1,cmp);
            for(int i=1;i<=m;i++)
                C[i]=0;
            long long ans=0;
            for(int i=1;i<=Count;i++){
                if(e[i].flag==0){
                    int l=lower_bound(t+1,t+m+1,e[i].l)-t-1,r=lower_bound(t+1,t+m+1,e[i].r)-t;
                    ans+=sum(r)-sum(l);
                }
                else{
                    int num=lower_bound(t+1,t+m+1,e[i].l)-t;
                    add(num,e[i].flag);
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ThinkPHP部署
    Linux下的vim常用操作
    Linux常用命令
    PHP中常用操作文件的方法
    PHP中的错误处理机制
    06 webpack4.0学习笔记——配置文件_sass-loader使用
    05 webpack4.0学习笔记——配置文件_babel-loader使用
    04 webpack4.0学习笔记——配置文件_url-loader使用
    03 webpack4.0学习笔记——配置文件_入口出口
    02 webpack4.0学习笔记——安装、基本命令
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9797535.html
Copyright © 2020-2023  润新知