1009. Triple Inversions (35)解题报告

来源:互联网 发布:nginx 302 found 编辑:程序博客网 时间:2024/06/15 00:18

首先感谢神赐予我智慧和力量。



这道题既可以用分块思想解决(O(n^1.5)),也可以用树状数组解决(O(nlogn))。这道题可能存在相同数字,因此需要遍历整个输入两遍。解题过程中我参考了《计算机 考研复试上机指导全书》。long long类型需要对应%lld才能正确输出。

分块思想如下



树状数组攻略如下











图侵删。


另外参考了以下博客:

PAT (Top Level) Practise 1009 Triple Inversions (35)

1009. Triple Inversions (35)





#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstdlib>#include <cstring>const int maxn = 1e5 + 10;int c[maxn], n;void update(int x, int v);int getSum(int x);inline int lowbit(int i) {return i&-i;}int main(void) {int i, tmp, *arr, *left, *right;long long num;setvbuf(stdin, new char[1 << 20], _IOFBF, 1 << 20);scanf("%d", &n);arr = (int *)calloc(n + 1, sizeof(int));left = (int *)calloc(n + 1, sizeof(int));right = (int *)calloc(n + 1, sizeof(int));num = 0;for (i = 1; i <= n; i++) {scanf("%d", &arr[i]);update(arr[i], 1);left[i] = i - 1 - getSum(arr[i] - 1);}memset(c, 0, sizeof(int) * maxn);for (i = n; i > 0; i--) {update(arr[i], 1);right[i] = getSum(arr[i] - 1);}for (i = 1; i <= n; i++) {num += (long long)left[i] * right[i];}printf("%lld", num);free(left);free(arr);free(right);return 0;}void update(int x, int v) {int i;for (i = x; i <= n; i += lowbit(i)) {c[i] += v;}return;}int getSum(int x) {int sum = 0, i;for (i = x; i > 0; i -= lowbit(i)) {sum += c[i];}return sum;}


0 0
原创粉丝点击