zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 10 D. Nested Segments (树状数组)

    题目链接:http://codeforces.com/problemset/problem/652/D

    给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间。

    我是先把每个区间看作整体,按照R从小到大排序。然后从最小的R开始枚举每个区间,要是枚举到这个区间L的时候,计算之前枚举的区间有多少个Li在L之后,那么这些Li大于L的区间的数量就是答案。那我每次枚举的时候用树状数组add(L , 1) 说明在L这个位置上出现了区间,之后枚举的时候计算L之前的和,然后i - 1 - sum(L)这个就是答案。(跟用树状数组计算逆序对有点类似,自己模拟一下就明白了)。

    但是区间的L和R很大,区间的个数又不是很多。所以我用离散化,区间的大小包含1到2n这些数。我用map做的,也可以用二分。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <map>
     6 using namespace std;
     7 const int MAXN = 4e5 + 10;
     8 struct data {
     9     int l , r , pos;
    10 }a[MAXN];
    11 int ans[MAXN] , n , bit[MAXN] , x[MAXN * 2];
    12 map <int , int> mp;
    13 bool cmp(data x , data y) {
    14     return x.r < y.r;
    15 }
    16 int sum(int i) {
    17     int s = 0;
    18     while(i > 0) {
    19         s += bit[i];
    20         i -= (i&-i);
    21     }
    22     return s;
    23 }
    24 
    25 void add(int i , int x) {
    26     while(i <= n*2) {
    27         bit[i] += x;
    28         i += (i&-i);
    29     }
    30 }
    31 
    32 int main()
    33 {
    34     scanf("%d" , &n);
    35     int cont = 0;
    36     for(int i = 1 ; i <= n ; i++) {
    37         scanf("%d %d" , &a[i].l , &a[i].r);
    38         x[++cont] = a[i].l;
    39         x[++cont] = a[i].r;
    40         a[i].pos = i;
    41     }
    42     sort(x + 1 , x + cont + 1);
    43     for(int i = 1 ; i <= cont ; i++) {
    44         mp[x[i]] = i;
    45     }
    46     sort(a + 1 , a + n + 1 , cmp);
    47     for(int i = 1 ; i <= n ; i++) {
    48         a[i].l = mp[a[i].l];
    49         a[i].r = mp[a[i].r];
    50     }
    51     for(int i = 1 ; i <= n ; i++) {
    52         ans[a[i].pos] = i - 1 - sum(a[i].l);
    53         //cout << a[i].l << "  " << a[i].r << "    " << sum(a[i].l) << endl;
    54         add(a[i].l , 1);
    55     }
    56     for(int i = 1 ; i <= n ; i++) {
    57         printf("%d
    " , ans[i]);
    58     }
    59 }
  • 相关阅读:
    Uva1595 对称轴
    Uva712 S树
    Uva673 平衡的括号
    leetcode102 二叉树的层次遍历
    Uva10191 复合词
    C++ multimap的用法
    Uva1103 古代象形符号
    UVa10763 交换学生
    C++ 优先级队列 priority_queue
    ios,zepto穿透解决方案
  • 原文地址:https://www.cnblogs.com/Recoder/p/5323688.html
Copyright © 2011-2022 走看看