zoukankan      html  css  js  c++  java
  • 【线段树】【4-6组队赛】Problem H

    Problem Description

    #include <iostream>
    #include <algorithm>
    using namespace std;

    int n,a[110000],b[110000],c[110000],d[110000];
    int main()
    {
          while(cin>>n)
          {
                for(int i=0;i<n;++i)  cin>>a[i];
                for(int i=0;i<n;++i)  cin>>b[i];
                for(int i=0;i<n;++i)  cin>>c[i];
                for(int i=0;i<n;++i)  cin>>d[i];

                for(int i=0;i<n;++i)
                      if(a[i]>b[i])  swap(a[i],b[i]);
                for(int i=0;i<n;++i)
                      if(c[i]>d[i])  swap(c[i],d[i]);

                for(int i=0;i<n;++i)
                {
                      int ans=0;
                      for(int j=0;j<n;++j)
                            if(a[i]<=c[j]&&d[j]<=b[i])  ans++;
                      cout<<ans<<endl;
                }
          }
          return 0;
    }


    Even you are brave enough still, I really not recommend you to copy the code and just submit it.

    Input

    Input contains several cases.
    Each case begins with an integer n (0<n<=100000).
    Then follow with 4 lines representing a[ ],b[ ],c[ ] and d[ ], all values are located in [1,100000].

    Output

    For each case, just write out the answer as what the code do.

    Sample Input

    4
    1 1 1 2
    1 1 1 2
    1 1 1 1
    1 1 1 1

    Sample Output

    4
    4
    4
    0


    题目大意:

    给你二组线段A,B 询问A组中每一个线段包含了多少B组线段


    将A,B按左端点排序;

    那么当B前面线段若不满足当前A了 ,就可以废弃不用了,即B.x<A[now].x。


    所以未被删除的B线段都是满足了左端点,现在只需要求是否满足右端点即可。

    用线段树来维护B的右端点。若B一条废弃不用,更新线段树即可。每次查询【0-A[now].y】有多少元素即可


    nlogn的复杂度。


    最后还要按序号排序回来,因为要按输入顺序输出,代码如下:


    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int maxn=100000+5;
    struct node
    {
        int x,y,num,ans;
    }A[maxn],B[maxn];
    int n;
    int tree[maxn<<2];
    bool cmp(node a,node b)
    {
        return a.x<b.x;
    }
    bool cmp1(node a,node b)
    {
        return a.num<b.num;
    }
    void pushup(int rt)
    {
        tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    }
    int build(int l,int r,int rt)
    {
        if(l==r) {tree[rt]=0;return 0;}
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    int updata(int p,int k,int l,int r,int rt)//单点更新
    {
        int m;
        if(l==r) {tree[rt]+=k;return 0;}
        m=(l+r)>>1;
        if(p<=m) updata(p,k,lson);
        else updata(p,k,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int temp=0,m;
        if(L<=l&&r<=R) return tree[rt];
        m=(l+r)>>1;
        if(L<=m) temp=temp+query(L,R,lson);
        if(R>m)  temp=temp+query(L,R,rson);
        return temp;
    }
    void input()
    {
                for(int i=0;i<n;++i)  {scanf("%d",&A[i].x);A[i].num=i;}
                for(int i=0;i<n;++i)  scanf("%d",&A[i].y);
                for(int i=0;i<n;++i)  scanf("%d",&B[i].x);
                for(int i=0;i<n;++i)  scanf("%d",&B[i].y);
                    for(int i=0;i<n;++i)
                      if(A[i].x>A[i].y)  swap(A[i].x,A[i].y);
                    for(int i=0;i<n;++i)
                      if(B[i].x>B[i].y)  swap(B[i].x,B[i].y);
                sort(B,B+n,cmp);
                sort(A,A+n,cmp);
    }
    void solve()
    {
         int tot=0;
         for(int i=0;i<n;i++)
         {
            updata(B[i].y,1,1,maxn-1,1);
         }
         for(int i=0;i<n;i++)
         {
            int ans=0;
            while(B[tot].x<A[i].x&&tot<n) {
                                        updata(B[tot].y,-1,1,maxn-1,1);
                                        tot++;
                                   }
            ans=query(1,A[i].y,1,maxn-1,1);
            A[i].ans=ans;
         }
         sort(A,A+n,cmp1);
         for(int i=0;i<n;i++) printf("%d
    ",A[i].ans);
    }
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    int main()
    {
       //  init();
    	while(scanf("%d",&n)!=EOF)
        {
            input();
            build(1,maxn-1,1);
            solve();
        }
    }





  • 相关阅读:
    Douglas-Peucker 轨迹压缩算法
    Marching squares 算法 获取轮廓(contour tracing)
    创建Mesh->格子地图转NavMesh->可破坏墙壁
    StretchedBillboard 实现
    程序员的微创业
    买云服务器有推荐吗?国内知道有腾讯云、阿里云...等等,不知道该选哪个好了,另外优惠吗?
    我的阿里云5年
    2021阿里云、腾讯云、华为云、滴滴云评测比较
    终于找到可以一文多发的平台了!
    2019年最新阿里云主机优惠购买指南
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480377.html
Copyright © 2011-2022 走看看