您的位置:首页 > 其它

1009. Triple Inversions (35)解题报告

2017-01-18 08:44 309 查看
首先感谢神赐予我智慧和力量。

这道题既可以用分块思想解决(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: