HDU_2689_Sort it
其实,这道题暴力也行,两个for就搞定了,时间复杂度为O(N^2),而树状数组的时间复杂度为O(N*logN)。
树状数组求逆序对的原理:
前面有i-1个数,把每次输入的数看作树状数组的下标,设置增加的变量为1,算其前缀和(有多少个1就有多少个顺序对),然后减去顺序对就是答案,方案有两种(本质是一样的):
1、
ans+=(i-1-sum(a));
add(a);
2、
add(a);
ans+=(i-sum(a));
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<queue> using namespace std; #define N 1005 int c[N]; int sum(int x) { int ret=0; while(x) { ret+=c[x]; x-=(x&-x); } return ret; } void add(int x) { while(x<=N) { c[x]++; x+=(x&-x); } } int main() { int t,a,ans; while(~scanf("%d",&t)) { memset(c,0,sizeof(c)); ans=0; for(int i=1;i<=t;++i) { scanf("%d",&a); add(a); ans+=(i-sum(a)); } printf("%d\n",ans); } return 0; }