http://acm.nyist.net/JudgeOnline/problem.php?pid=117
用树状数组做,一定要注意sort 的特性,当元素的值很大的时候sort 是不稳定的,所以我们要把sort 变成稳定的排序
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int c[1000010],b[1000010],n;
struct A
{
int v,index;
A(){}
A(int v,int index):v(v),index(index){}
bool operator < (const A& rhs) const//排序的时候先按元素排,然后按照下表排,把sort 变成稳定的排序
{
if(v != rhs.v)
return v < rhs.v;
else return index < rhs.index;
}
}a[1000010];
int lowbit(int x)
{
return x & (-x);
}
void add(int x,int y)
{
while(x <= n)
{
c[x] += y;
x += lowbit(x);
}
}
int query(int x)
{
int ans = 0;
while(x > 0)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int m,T;
cin>>T;
while(T--)
{
cin>>n;
memset(c,0,sizeof(c));
//memset(b,0,sizeof(b));
int i;
long long res = 0;
for(i = 1; i <= n; i++)
{
cin>> a[i].v;
a[i].index = i;
}
sort(a+1,a+n+1);
for(i = 1; i <= n; i++)
b[a[i].index] = i;
for(i = 1; i <= n; i++)
//cout<<b[i]<<"***"<<endl;
for(i = 1; i <= n; i++)
{
res += i -1 - query(b[i]-1);
add(b[i],1);
}
cout<<res<<endl;
}
return 0;
}
归并排序:
#include<stdio.h>
int a[1000005],temp[1000005];
long long sum;
void merge(int l ,int mid,int r)
{
int i = l, j = mid+1,k = l;
while(i <= mid && j <= r)
{
if(a[i] <= a[j])
{
temp[k++] = a[i++];
}
else
{
temp[k++] = a[j++];
sum += mid - i+1;
}
}
while(i <= mid) temp[k++] = a[i++];
while(j <= r) temp[k++] = a[j++];
for(i = l; i <= r ;i++)
a[i] = temp[i];
}
void msort(int l, int r)
{
if(l == r) return ;
int mid = (l + r)/2;
msort(l,mid);
msort(mid+1,r);
merge(l,mid,r);
}
int main()
{
int i,n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i = 0;i < n; i ++)
scanf("%d",&a[i]);
sum = 0;
msort(0,n - 1);
printf("%lld\n",sum);
}
return 0;
}