#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=5555;
int sum[maxn<<2];
void pushup(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
/*void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Build(int l,int r,int rt){
sum[rt]=0;
if(l==r)return ;
int mid=(l+r)>>1;
Build(lson);
Build(rson);
}
*/
void Build(int l,int r,int rt)
{
sum[rt] = 0;
if (l == r) return ;
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
}
void update(int p,int l,int r,int rt)
{ if (l == r)
{
sum[rt] ++; return ;
}
int mid = (l + r) >> 1;
if (p <= mid) update(p , lson);
else update(p , rson);
pushup(rt);
}
/*
void update(int p,int l,int r,int rt){
if(l==r){
sum[rt]++;
return ;
}
int mid=(l+r)>>1;
if(p<=mid)update(p,lson);
else update(p,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
int mid=(l+r)/2;
int ret=0;
if(L<=mid)ret+=query(L,R,lson);
if(R>mid)ret+=query(L,R,rson);
return ret;
}
*/
int query(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
{ return sum[rt];
}
int mid = (l + r) >> 1;
int ret = 0;
if (L <= mid) ret += query(L , R , lson);
if (R > mid) ret += query(L , R , rson);
return ret;
}
int x[5555];
int main() {
int n;
while (~scanf("%d",&n))
{
Build(0 , n - 1 , 1);
int sum = 0;
for (int i = 0 ; i < n ; i ++)
{
scanf("%d",&x[i]);
sum += query(x[i] , n - 1 , 0 , n - 1 , 1);
update(x[i] , 0 , n - 1 , 1);
}
int ret = sum;
for (int i = 0 ; i < n ; i ++)
{
sum += n - x[i] - x[i] - 1;
ret = min(ret , sum);
}
printf("%d\n",ret);
}
return 0;
}
【题目】: HDU1394
【题意】:求inversion之后的最小逆序数
【题解】:用O(logn)求出最初的逆序数之后,可以用O(1)来推出最后的逆序数
【代码】: