zoukankan      html  css  js  c++  java
  • codeforces 652D D. Nested Segments(离散化+sort+树状数组)

    题目链接:

    D. Nested Segments

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given n segments on a line. There are no ends of some segments that coincide. For each segment find the number of segments it contains.

    Input

    The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of segments on a line.

    Each of the next n lines contains two integers li and ri ( - 109 ≤ li < ri ≤ 109) — the coordinates of the left and the right ends of the i-th segment. It is guaranteed that there are no ends of some segments that coincide.

    Output

    Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.

    Examples
    input
    4
    1 8
    2 3
    4 7
    5 6
    output
    3
    0
    1
    0
    input
    3
    3 4
    1 5
    2 6
    output
    0
    1
    1

    题意:给n个线段,对于每个线段问它覆盖了多少个线段;
    思路:由于线段端点是在e9范围内,所以要先离散化到2e5内,只离散化一个端点即可,我离散化的是右端点,然后在对左端点排序(保证l[i]>=l[j]),然后再按顺序query右端点(保证r[i]<r[j])并update,就可以得到结果了,感觉线段树和树状数组真是丧心病狂;还有以前不会离散化,昨天睡觉的时候居然自己就领悟了,哈哈哈哈哈,开心;
    AC代码:
    /*2014300227 652D - 24 GNU C++11 Accepted 187 ms 5948 KB */
    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+3;
    int n,sum[N],ans[N];
    struct node
    {
        int l,r,id;
    };
    node qu[N];
    bool cmp1(node x,node y)
    {
        if(x.r==y.r)return x.l<y.l;
        return x.r<y.r;
    }
    bool cmp2(node x,node y)
    {
        if(x.l==y.l)return x.r<y.r;//注意此处的大小关系,因为我把右端点相等的离散化成不等的了;
        return x.l>y.l;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x)
    {
        while(x<=n)
        {
            sum[x]++;
            x+=lowbit(x);
        }
    }
    int query(int x)
    {
        int s=0;
        while(x>0)
        {
            s+=sum[x];
            x-=lowbit(x);
        }
        return s;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&qu[i].l,&qu[i].r);
            qu[i].id=i;
        }
        sort(qu+1,qu+n+1,cmp1);//按右端点排序以离散化
        for(int i=1;i<=n;i++)
        {
            qu[i].r=i;//离散化
        }
        sort(qu+1,qu+n+1,cmp2);
        for(int i=1;i<=n;i++)
        {
            ans[qu[i].id]=query(qu[i].r);
            update(qu[i].r);
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d
    ",ans[i]);
        }
    
    
        return 0;
    }
  • 相关阅读:
    关于总线的总结
    我已经理解了并发和并行的区别
    关于CPU的一些基本知识总结
    shell生成指定长度的随机数
    进程、线程、协程、例程、过程的区别是什么?
    Perl输出带颜色行号或普通输出行
    Ruby数组(2):数组方法详细整理
    Linux find常用用法示例
    MariaDB官方手册翻译
    Ruby中to_s和to_str、to_i和to_int、to_a和to_ary、to_h和to_hash的解释说明
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5322733.html
Copyright © 2011-2022 走看看