• codeforces 652D


    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 ( - 10e9 ≤ li < ri ≤ 10e9) — 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.

    题意:给你n个区间问你每个区间包含了几个小区间,这些区间没有相交。

     求区间个数与线段树求逆序对方法差不多,先按右区间排序,再利用求逆序数的思想。还有由于区间数比较大但区间的个数少,要离散化一下。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <map>
    using namespace std;
    const int M = 2e5 + 10;
    struct ss {
        int x , y , num;
    }s[M];
    int m[M << 1] , ans[M << 1];
    bool cmp(ss a , ss b) {
        return a.y < b.y;
    }
    bool cmp1(ss a , ss b) {
        return a.num < b.num;
    }
    struct TnT {
        int l , r , sum;
    }T1[M << 4] , T2[M << 4];
    void build(TnT T[] , int l , int r , int p) {
        int mid = (l + r) >> 1;
        T[p].l = l , T[p].r = r , T[p].sum = 0;
        if(T[p].l == T[p].r) {
            return ;
        }
        build(T , l , mid , p << 1);
        build(T , mid + 1 , r , (p << 1) | 1);
    }
    void updata(TnT T[] , int pos , int p) {
        int mid =(T[p].l + T[p].r) >> 1;
        if(T[p].l == T[p].r && T[p].l == pos) {
            T[p].sum++;
            return ;
        }
        if(mid >= pos) {
            updata(T , pos , p << 1);
        }
        else {
            updata(T , pos , (p << 1) | 1);
        }
        T[p].sum = T[p << 1].sum + T[(p << 1) | 1].sum;
    }
    int query(TnT T[] , int l , int r , int p) {
        int mid = (T[p].l + T[p].r) >> 1;
        if(T[p].l == l && T[p].r == r) {
            return T[p].sum;
        }
        if(mid < l) {
            return query(T , l , r , (p << 1) | 1);
        }
        else if(mid >= r) {
            return query(T , l , r , p << 1);
        }
        else {
            return query(T , l , mid , p << 1) + query(T , mid + 1 , r , (p << 1) | 1);
        }
    }
    int main()
    {
        int n;
        while(cin >> n) {
            int MAX = 0;
            map mp;
            int cnt = 0;
            memset(s , 0 , sizeof(s));
            for(int i = 0 ; i < n ; i++) {
                cin >> s[i].x >> s[i].y;
                m[++cnt] = s[i].x;
                m[++cnt] = s[i].y;
                s[i].num = i;
                MAX = max(MAX , s[i].y);
            }
            sort(m + 1 , m + cnt + 1);
            for(int i = 1 ; i <= cnt ; i++) {
                mp[m[i]] = i;
            }
            build(T1 , 1 , cnt , 1);
            build(T2 , 1 , cnt , 1);
            sort(s , s + n , cmp);
            for(int i = 0 ; i < n ; i++) {
                updata(T1 , mp[s[i].y] , 1);
                updata(T2 , mp[s[i].x] , 1);
                ans[s[i].num] = min(query(T1 , 1 , mp[s[i].y] - 1 , 1) , query(T2 , mp[s[i].x] + 1 , cnt , 1));
            }
            for(int i = 0 ; i < n ; i++) {
                cout << ans[i] << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    web服务器的设置
    java数字图像处理常用算法(转)
    Delphi 7.0常用函数速查手册
    直方图均衡子函数
    Delphi6/7 中XML 文档的应用
    区域增长算法
    Java中的异常栈轨迹和异常链
    Arrays类和Collections的运用
    Java中内部类对象的创建以及hook机制
    Java中的容器
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6009568.html
Copyright © 2020-2023  润新知