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;
}
浙公网安备 33010602011771号