树状数组求逆序数的应用。。这一题设计的非常巧妙。。。下面说一下题意。。给定一组数,然后依次的挪动该组数的元素共得到n种序列。求这n中序列中逆序数最少的个数。。。杯具的是我竟然把树状数组和一般的数组弄混淆了。。这里要特别注意。。。不过值得一提的是竟然rank1,(*^__^*) 嘻嘻……
AC代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#define N 5005
using namespace std;
int s[N];
int kp[N];
int n;
int lowbit(int x)
{return x&(-x);}
void update(int x)
{ while(x<=n)
{ s[x]++;
x+=lowbit(x);
}
}
int Quary(int x)
{ int sum=0;
while(x>0)
{ sum+=s[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
while(~scanf("%d",&n))
{ int res=0;
memset(s,0,sizeof(s));
memset(kp,0,sizeof(kp));
for(int i=1;i<=n;++i)
{
scanf("%d",&kp[i]);
kp[i]++;
update(kp[i]);
res+=i-Quary(kp[i]);
}
int minn=res;
for(int i=n;i>=2;--i)
{ res+=2*kp[i]-n-1;//每移动一次增加kp[i]-1个逆序数,同时减少n-kp[i]个逆序数。。。
minn=min(minn,res);
}
printf("%d\n",minn);
}return 0;
}

本文深入探讨了利用树状数组解决逆序数问题的巧妙方法,提供了完整的AC代码解析,从题意解读到算法实现,详细展示了如何通过树状数组优化序列操作,降低时间复杂度,最终找到逆序数最少的序列排列。
976

被折叠的 条评论
为什么被折叠?



