
2020.2.9普及C组 数列(sequence)【纪中】【前缀和】【树状数组】【离散化】
发布日期:2021-05-07 13:06:46
浏览次数:26
分类:精选文章
本文共 1444 字,大约阅读时间需要 4 分钟。
前缀和、离散化以及树状数组是数据处理领域中常用的高级数据结构和算法,广泛应用于多个领域。以下将结合这三个技术手段,展示一个典型的解决方案。
代码如下:
#include#include #include #include #include using namespace std;long long a[100010], f[100010];long long n, m, c, ans, w;struct node { long long sum, place;};bool cmp(node a, node b) { return a.sum > b.sum;}bool cmp2(node a, node b) { return a.place < b.place;}int main() { freopen("sequence.in", "r", stdin); freopen("sequence.out", "w", stdout); cin >> n >> m; for (int i = 1; i <= n; ++i) { scanf("%lld", &a[i]); a[i] -= m; b[i].sum = b[i-1].sum + a[i]; b[i].place = i; if (b[i].sum >= 1) { ans++; } } sort(b + 1, b + n + 1, cmp); for (int i = 1; i <= n; ++i) { if (b[i].sum != w || i == 1) { c++; w = b[i].sum; } b[i].sum = c; } sort(b + 1, b + n + 1, cmp2); for (int i = 1; i <= n; ++i) { for (int j = b[i].sum - 1; j >= 1; j -= j & (-j)) { ans += f[j]; } for (int j = b[i].sum; j <= c; j += j & (-j)) { f[j]++; } } cout << ans << endl;}
以上代码实现了前缀和、离散化以及树状数组的结合使用。具体流程如下:
前缀和计算:首先遍历数组计算前缀和,并对每个前缀和进行离散化处理。
离散化处理:将前缀和转换为离散化后的值,以减少实际值的范围,提高计算效率。
树状数组操作:利用树状数组进行范围查询和点更新,实现高效的数据处理。
整个过程通过前缀和计算原始数据,离散化处理后再利用树状数组进行高效计算,最终得到最终结果。