zoukankan      html  css  js  c++  java
  • Counting Intersections

    Counting Intersections

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

    Problem Description
    Given some segments which are paralleled to the coordinate axis. You need to count the number of their intersection.

    The input data guarantee that no two segments share the same endpoint, no covered segments, and no segments with length 0.
     
    Input
    The first line contains an integer T, indicates the number of test case.

    The first line of each test case contains a number n(1<=n<=100000), the number of segments. Next n lines, each with for integers, x1, y1, x2, y2, means the two endpoints of a segment. The absolute value of the coordinate is no larger than 1e9.
     
    Output
    For each test case, output one line, the number of intersection.
     
    Sample Input
    2 4 1 0 1 3 2 0 2 3 0 1 3 1 0 2 3 2 4 0 0 2 0 3 0 3 2 3 3 1 3 0 3 0 2
     
    Sample Output
    4 0
    分析:对于横向线段只保留两个端点并记录类型,对竖向线段保留整个线段;
       离散化并排序,遍历竖向线段,对横向端点树状数组更新;
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define Lson L, mid, rt<<1
    #define Rson mid+1, R, rt<<1|1
    const int maxn=2e5+10;
    const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}};
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    int n,m,k,t,x[maxn],y[maxn],p[maxn],xcnt,ycnt,id,idx;
    ll ans;
    multiset<int>s;
    struct node
    {
        int x,low,high;
        bool operator<(const node&p)const
        {
            return x<p.x;
        }
    }a[maxn];
    struct node1
    {
        int x,y,type;
        bool operator<(const node1&p)const
        {
            return x<p.x;
        }
    }g[maxn];
    int get(int x)
    {
        int sum=0;
        for(int i=x;i;i-=(i&(-i)))
            sum+=p[i];
        return sum;
    }
    void add(int x,int y)
    {
        for(int i=x;i<=maxn-5;i+=(i&(-i)))
            p[i]+=y;
    }
    int main()
    {
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            xcnt=ycnt=id=idx=0;
            ans=0;
            memset(p,0,sizeof(p));
            scanf("%d",&n);
            rep(i,1,n)
            {
                int b,c,d,e;
                scanf("%d%d%d%d",&b,&c,&d,&e);
                if(c>e)swap(c,e);
                if(b>d)swap(b,d);
                if(b==d)
                {
                    x[++xcnt]=a[++id].x=b;
                    y[++ycnt]=a[id].low=c;
                    y[++ycnt]=a[id].high=e;
                }
                else
                {
                    x[++xcnt]=b;
                    x[++xcnt]=d;
                    y[++ycnt]=c;
                    g[++idx].x=b;
                    g[idx].y=c;
                    g[idx].type=0;
                    g[++idx].x=d;
                    g[idx].y=e;
                    g[idx].type=1;
                }
            }
            sort(x+1,x+xcnt+1);
            sort(y+1,y+ycnt+1);
            sort(a+1,a+id+1);
            sort(g+1,g+idx+1);
            int num1=unique(x+1,x+xcnt+1)-x-1;
            int num2=unique(y+1,y+ycnt+1)-y-1;
            rep(i,1,id)
            {
                a[i].x=lower_bound(x+1,x+num1+1,a[i].x)-x;
                a[i].low=lower_bound(y+1,y+num2+1,a[i].low)-y;
                a[i].high=lower_bound(y+1,y+num2+1,a[i].high)-y;
            }
            rep(i,1,idx)
            {
                g[i].x=lower_bound(x+1,x+num1+1,g[i].x)-x;
                g[i].y=lower_bound(y+1,y+num2+1,g[i].y)-y;
            }
            int now=1;
            rep(i,1,id)
            {
                while(now<=idx&&g[now].x<=a[i].x)
                {
                    if(g[now].type==0)add(g[now].y,1);
                    else {
                            if(g[now].x!=a[i].x)
                            add(g[now].y,-1);
                            else s.insert(g[now].y);
                    }
                    now++;
                }
                ans+=get(a[i].high)-get(a[i].low-1);
                for(int x:s)add(x,-1);
                s.clear();
            }
            printf("%lld
    ",ans);
        }
        //system("Pause");
        return 0;
    }
  • 相关阅读:
    解决Sqlite Developer过期的最简单办法(转自百度经验)
    (转)解决!Visual Studio 遇到了异常。这可能是由某个扩展导致的。
    【转】VC中的class“std::vector<_Ty>”需要有 dll 接口由 class“Test”的客户端使用错误
    切换日语输入法找不到MicrosoftIME键盘选项了
    ps如何拆分图片
    码农应该注意保持的习惯
    "指定的文件格式无法识别或为不支持的二进制"
    编译FlashDemo遇到问题:Error "pFlashUI未定义的标识符"
    GridView,GridLayout
    Android,ArrayList,List,Set等
  • 原文地址:https://www.cnblogs.com/dyzll/p/5790162.html
Copyright © 2011-2022 走看看