c++ - 一个数字在所有查询中出现的次数?
问题描述
取一个未排序的数组,如:
4,5,1,2,3,7,8,3
查询如下:
[1 2] [5 5] [2 6] [6 6] [1 6] [1 5]
其中每个查询代表一个索引区间。
数组和总查询的长度可以达到100000。
我想计算每个查询中每个索引的出现次数,如下所示:
发生率 1: 3
发生 3: 3
5:4等的出现
执行此操作的任何最佳方法?我以天真的方式尝试过,但需要一些提示以获得最佳解决方案。
解决方案
您可以通过BIT(二叉索引树)或Segment-Tree来解决它。
我在那里附上了两个链接来了解这些算法......
比特解决方案:
对于每个查询,让范围[l r]
::
- 现在您需要在 BIT
l to n
中使用 value进行更新1
。 - 现在你需要排除更新
r+1 to n
......所以用BITr+1 to n
中的值更新......-1
每个更新操作都在 BIT 中记录 log(n)...
计算每个索引的出现次数:
Call sum(index) in BIT to get count
此操作需要 log(n) 时间..
复杂:
该解决方案的复杂性:Q*(log(n)+log(n)) + N *(log(n))
..
代码:
#include <bits/stdc++.h>
using namespace std;
int tree[100005], A[100005];
void update(int idx, int n, int v) {
while (idx <= n) {
tree[idx] += v;
idx += (idx & -idx);
}
}
int sum(int idx) {
int res = 0;
while (idx) {
res += tree[idx];
idx -= (idx & -idx);
}
return res;
}
int main() {
int n, q, i, l, r;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
scanf("%d", &A[i]);
}
scanf("%d", &q);
memset(tree, 0, sizeof(tree));
while (q--) {
scanf("%d%d", &l, &r);
update(l,n,1);
update(r+1,n,-1);
}
for (i = 1; i <= n; i++) {
printf("%d\n", sum(i));
}
return 0;
}
推荐阅读
- excel - 我想在 excel vba 中创建 21 个表,但我得到 Argument not optional 错误
- php - Laravel 在 POST 方法中从 multipart/form-data 获取请求
- pandoc - 如何防止 pandoc 插入
- r - 具有相同 CRS 但裁剪时无输出的 Shapefile 和 Raster
- r - 如果表1中的日期早于表2中的日期,则R函数连接两个表
- web-services - 来自 QlikView 扩展对象的 jquery ajax 请求发送 OPTION 而不是 GET(在 Fiddler 中检查)
- javascript - 如何推进猫鼬搜索?
- mule4 - 比较两个变量并计算第三个变量并将其附加到 mule4 中的现有变量
- sql - DB2,按年份分组和求和,其中年份是列值
- python - Python 在使用 fast_executemany = True 和 Sybase 表插入时因“字符串数据,右截断”而崩溃