POJ 2299
用归并排序求逆序对,用时391ms,但是用树状数组的话runtime error。
#include <stdio.h> #include <string.h> const int N=500000; int a[N], b[N], n; __int64 Calc(int first, int last) { if (first == last-1) return 0; int mid = (first+last)/2, i = first, j = mid, k = first; __int64 res = Calc(first, mid)+Calc(mid, last); while (i < mid && j < last) { if (a[i] <= a[j]) b[k++] = a[i++], res += j-mid; else b[k++] = a[j++]; } while (i < mid) b[k++] = a[i++], res += j-mid; while (j < last) b[k++] = a[j++]; memcpy(a+first, b+first, sizeof(b[0])*(last-first)); return res; } int main() { while( scanf("%d", &n),n){ for (int i = 0; i < n; ++i) scanf("%d", &a[i]); printf("%I64d\n", Calc(0, n)); } return 0; }
树状数组:
#include <stdio.h> const int N=500000; int a[N+1]; void Inc(int x) { for (; x <= N; x += (x^x-1)&x) ++a[x]; } __int64 Sum(int x) { __int64 res = 0; for (; x; x -= (x^x-1)&x) res += a[x]; return res; } int main() { int n;__int64 res; while(scanf("%d",&n)!=EOF,n) { res=0; while(n--) { int t; scanf("%d", &t); res += Sum(N-t); Inc(N-t+1); } printf("%I64d\n", res); } return 0; }