当前位置: 代码迷 >> 综合 >> Array Optimization by Deque (cf)树状数组
  详细解决方案

Array Optimization by Deque (cf)树状数组

热度:29   发布时间:2023-11-23 06:04:09.0

原题链接:Problem - 1579E2 - Codeforces

今天学了树状数组,好牛,一个题想了一晚上才明白呜呜

1.首先这个题要想明白,每次插入一个数的时候,如果这个数插在队列的最前面,那么对ans有贡献的就是所有小于这个数的个数;如果插在队列的最后面,那么对ans有贡献的就是所有大于这个数的个数。因此也可以想到,每次插入一个数的时候,与前面的那些数的排列顺序无关,只跟它自己插在最前面还是最后面有关,所以找到前面和后面贡献的最小值就ok了。

2.数的范围较大,可以离散化将每个数变成它们相应的序号

这里有两种方法:

(1)排序&去重

去重了之后相同的数拥有相同的序号;

(2)排序&不去重

不去重的话相同的数有相同的序号,可能会出现序号为1 1 2 4 4这样的情况,即没有3这个序号

但是其实想一下,(1)也会最后少了一些后面的序号,所以没关系,最后用c[i]树状数组都是一样的用。

3.用树状数组维护区间

求小于等于一个序号的所有个数 : for (int j = a[i]; j; j -= j & -j) res1 += c[j];

是从这个序号往前,所以 j -= j & -j

这个地方还有一个点,求所有小于a[i]的个数,是用 for (int j = a[i]; j; j -= j & -j) res1 += c[j];

求所有大于a[i]的个数,是先算出所有小于等于a[i]的个数for (int j = a[i]; j; j -= j & -j) res2 += c[j];

然后,在这个数插入之前,队列中一共有i - 1个数,所以大于a[i]的个数为i - 1 - res2。

4.a[]最后储存的是原储存的a[]数组离散化后的各个值自己的序号,对a[]循环的时候,记得每次在最后for (int j = a[i]; j <= n; j += j & -j) c[j]++;

5.树状数组的下标(序号)是从1开始的,所以:

for (int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b;

算序号的时候是减去b,相当于减去0;

6.因为有多个测试样例,记得每次归零:

  for (int i = 1; i <= n; i++) c[i] = 0;  (从1到n就行了,树状数组序号最大到n)

#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef pair<int, int> PII;
#define rep(i, m, n) for (int i = (m); i <= (n); ++i)
#define rrep(i, m, n) for (int i = (m); i >= (n); --i)
typedef long long ll;const int N = 200010;
int a[N], b[N], c[N];int main() {int t, n;cin >> t;while (t--) {cin >> n;for (int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i];for (int i = 1; i <= n; i++) c[i] = 0;sort(b + 1, b + n + 1);for (int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b;long long ans = 0;for (int i = 1; i <= n; i++) {int res1 = 0, res2 = 0;for (int j = a[i] - 1; j; j -= j & -j) res1 += c[j];for (int j = a[i]; j; j -= j & -j) res2 += c[j];res2 = i - 1 - res2;ans += min(res1, res2);for (int j = a[i]; j <= n; j += j & -j) c[j]++;}cout << ans << endl;}return 0;
}

  相关解决方案