A - Ultra-QuickSort
其实我好好想了一下树状数组到底可以干什么呢它可以统计在某一个数字出现的时候,在它之前有多少个已经出现想要求算比它小的数字的和的话就是在离散化下标后向后数值更新;
奶牛排序两者全都考察到了;
https://cn.vjudge.net/contest/234987#status/16110581005/S/0/
https://cn.vjudge.net/contest/234987#problem/A
昨天又把树状数组看了一下,觉得就是统计出现的数字的个数,求逆序对就是这个的典型例题
并且经过这道题目我也把什么是离散化好好的给弄懂了;
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int Max = 1e6+5;
long long a[Max],b[Max];
int lowbit(int x)
{
return x&(-x);
}
int n;
long long c[Max];
void add(int x,int num)
{
while(x<=n)
{
c[x]+=num;
x+=lowbit(x);
}
}
long long query(int x)
{
long long s=0;
while(x>=1)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int du[Max];
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+1+n,a[i])-b;
}//离散化处理;
memset(c,0,sizeof(c));
memset(du,0,sizeof(du));
long long sum=0;
for(int i=n;i>=1;i--)
{
du[a[i]]++;//防止相等的数也被数成是逆序对所以要把它给剪掉;
//5 5 5 4 4这种情况;
add(a[i],1);
sum+=query(a[i])-du[a[i]];
}
printf("%lld\n",sum);
}
return 0;
}