【AtCoder】离线询问+树状数组

简介: 笔记

题目描述



input#1:


2 3 1

1 1

1 2

2 2

1 2


output#1:


3


input#2:


10 3 2

1 5

2 8

7 10

1 7

3 10


output#2:


1

1


input#3:


10 10 10

1 6

2 9

4 5

4 7

4 7

5 8

6 6

6 7

7 9

10 10

1 8

1 9

1 10

2 8

2 9

2 10

3 8

3 9

3 10

1 10


output#3:


7

9

10

6

8

9

6

7

8

10


题意



17.png

思路


如本文标题,我们需要对询问离线处理,这样对于区间询问,我们就可以进行排序,并使得左端点单调增,以便处理后续问题。


考虑用树状数组维护区间右端点,所以可以先将所有的区间的右端点加入树状数组中。在每次询问一个区间 [ l , r ] [l, r][l,r] 时,删掉所有区间左端点小于 l ll 的树状数组中右端点的值。然后直接进行查询当前右端点小于等于 r rr 的值的个数,即位该询问的结果。


代码


class BIT {
public:
  BIT() { memset(tr, 0, sizeof tr); }
  int tr[N];
  void add(int x, int v = 1) { for (; x < N; x += x & -x) tr[x] += v; }
  int sum(int x) { int res = 0; for (; x; x -= x & -x) res += tr[x]; return res; }
};
int n, m, q;
struct node {
  int l, r;
  int id;
  bool operator<(const node &A) const {
    if (l == A.l) return r < A.r;
    return l < A.l;
  }
}; 
node a[N], b[N];
int res[N];
void solve() {
  cin >> n >> m >> q;
  BIT tree;
  for (int i = 1; i <= m; i++) {
    int l, r; cin >> l >> r;
    a[i] = {l, r};
    tree.add(r, 1);
  }
  for (int i = 1; i <= q; i++) {
    int l, r; cin >> l >> r;
    b[i] = {l, r, i}; 
  }
  sort(a + 1, a + 1 + m);
  sort(b + 1, b + 1 + q);
  int j = 1;
  for (int i = 1; i <= q; i++) {
    int l = b[i].l, r = b[i].r, id = b[i].id;
    while (j <= m && a[j].l < l) {
      tree.add(a[j].r, -1);
      j++;
    }
    res[id] = tree.sum(r);
  }
  for (int i = 1; i <= q; i++) {
    cout << res[i] << endl;
  }
}
相关文章
|
人工智能
牛客-小H的询问(线段树)
牛客-小H的询问(线段树)
102 0
合并有序数组(跑路人笔记)
合并有序数组(跑路人笔记)
|
9月前
|
算法 vr&ar 图形学
☆打卡算法☆LeetCode 187. 重复的DNA序列 算法解析
☆打卡算法☆LeetCode 187. 重复的DNA序列 算法解析
|
9月前
|
SQL 算法 vr&ar
☆打卡算法☆LeetCode 182. 查找重复的电子邮箱 算法解析
☆打卡算法☆LeetCode 182. 查找重复的电子邮箱 算法解析
☆打卡算法☆LeetCode 182. 查找重复的电子邮箱 算法解析
|
存储 人工智能
树状数组专题【完结】
1 国外的论文点击打开链接 2 我的总结点击打开链接 任何能够造成树状数组下表为0的操作都会使得程序TLE,这是个很重要的地方! 第一题 poj 2299 Ultra-QuickSort 点击打开poj 2299 思路: 离...
1134 0
|
机器学习/深度学习 存储 算法
初级算法之数组(完结)
数组 删除有序数组中的重复项 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。 将最终结果插入 nums 的前 k 个位置后返回 k 。 不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 思路及代码 遍历数组的每一个数,如果当前元素和下一个元素不一样,那么就加一. c
115 0
|
算法 C++
【数独 1】不回溯,试试候选数法1ms高效解数独谜题-C++实现(上)
【数独 1】不回溯,试试候选数法1ms高效解数独谜题-C++实现(上)
155 0
|
算法 C++
【数独 1】不回溯,试试候选数法1ms高效解数独谜题-C++实现(下)
【数独 1】不回溯,试试候选数法1ms高效解数独谜题-C++实现(下)
122 0
|
9月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-101 图形显示
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-101 图形显示
37 0
|
9月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-87 字串统计
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-87 字串统计
52 0

热门文章

最新文章