• CF


    题目传送门

    题解:

    可以将所有线段按照左端点优先小,其次右端点优先大进行排序。

    然后对于第 i 条线段来说, 那么第 i+1 ---- n 的线段左端点都一定在第i条线段的右边, 接下来就需要知道 i+1 ---- n 中的这些线段有多少条的右端点是在第 i 条线段的右端点的左边。

    可以通过一个树状数组来维护一个右端点的前缀合。

    当我门处理第i条线段的时候, 先将第i条线段的右端点从树状数组里面删除,然后在询问在 r 之前有多少个右端点就是相应的答案了。

    代码:

    /*
    code by: zstu wxk
    time: 2019/02/23
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 5e5 + 100;
    struct Node{
        int l, r, id;
        bool operator< (const Node & x) const{
            if(l == x.l) return r > x.r;
            return l < x.l;
        }
    }A[N];
    int b[N];
    int k = 0, n;
    int F(int x){
        return lower_bound(b+1, b+1+k, x) - b;
    }
    int tree[N];
    void Updata(int x, int c){
        while(x <= k){
            tree[x] += c;
            x += x & (-x);
        }
        return ;
    }
    int Query(int x){
        int ret = 0;
        while(x > 0){
            ret += tree[x];
            x -= x & (-x);
        }
        return ret;
    }
    int ans[N];
    void Ac(){
        for(int i = 1; i <= n; ++i){
            scanf("%d%d", &A[i].l, &A[i].r);
            A[i].id = i;
            b[++k] = A[i].l;
            b[++k] = A[i].r;
        }
        sort(A+1, A+1+n);
        sort(b+1, b+1+k);
        k = unique(b+1, b+1+k) - (b+1);
        for(int i = 1; i <= n; ++i)
            Updata(F(A[i].r), 1);
        for(int i = 1; i <= n; ++i){
            Updata(F(A[i].r), -1);
            ans[A[i].id] = Query(F(A[i].r));
        }
        for(int i = 1; i <= n; ++i)
            printf("%d
    ", ans[i]);
    }
    int main(){
        while(~scanf("%d", &n)){
            Ac();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    返回一个整数数组中最大子数组的和 1
    软件工程第一周开课博客
    体温上报系统总结
    Android 布局中如何使控件居中
    Android:Unable to find explicit activity class报错
    Android Studio 线性布局
    相对布局
    HTML5 video视频
    阅读笔记——《人月神话》
    体温汇报系统界面
  • 原文地址:https://www.cnblogs.com/MingSD/p/10422960.html
Copyright © 2020-2023  润新知