#include<stdio.h><br />#define N 5005</p><p>struct node{<br /> int l;<br />int r;<br />int sum;<br />};</p><p>int arr[N];<br />node tree[3*N];</p><p>void buid_tree(int k,int left,int right)<br />{<br />int mid;<br />int L,R;<br />tree[k].l = left; tree[k].r = right;<br />if(right-left == 1){<br />tree[k].sum = 0;<br />return ;<br />}<br />L = 2*k; R = L+1;<br />mid = (left+right)/2;<br />buid_tree(L,left,mid);<br />buid_tree(R,mid,right);<br />tree[k].sum = tree[L].sum+tree[R].sum;<br />return ;<br />}</p><p>int tree_search(int k,int left,int right)<br />{<br />int mid;<br />int L,R;<br />int ls = 0,rs = 0;<br />if(left <= tree[k].l && right >= tree[k].r){<br /> return tree[k].sum;<br />}<br />L = 2*k; R = L+1;<br />mid = (tree[k].l+tree[k].r)/2;<br />if(left < mid) ls = tree_search(L,left,right);<br />if(right > mid) rs = tree_search(R,left,right);<br />return ls+rs;<br />}</p><p>void tree_insert(int k,int left,int right)<br />{<br />int mid;<br />int L,R;<br />if(left <= tree[k].l && right >= tree[k].r){<br /> tree[k].sum += 1;<br /> return ;<br />}<br />L = 2*k; R = L+1;<br />mid = (tree[k].l+tree[k].r)/2;<br />if(left < mid) tree_insert(L,left,right);<br />if(right > mid) tree_insert(R,left,right);<br />tree[k].sum = tree[L].sum+tree[R].sum;<br />return ;<br />}</p><p>int main()<br />{<br />int i;<br />int m;<br />int n;<br />int flag;<br />int count;<br />int min;<br />while(scanf("%d",&n) == 1){<br />count = 0;<br />buid_tree(1,0,N+1);<br /> for(i = 1;i <= n;i++){<br /> scanf("%d",&arr[i]);<br />count += i-1-tree_search(1,0,arr[i]);<br />tree_insert(1,arr[i],arr[i]+1);<br />}<br />min = count;<br />for(m = 1;m <= n-1;m++){<br />flag = tree_search(1,0,arr[m]);<br />count = count-flag+(n-1-flag);//之前太暴力了,每個序列都建一次樹求出逆序數,果斷逾時了,後來百度了一下,才想到了這樣,<br />if(count < min) //每移動一個,逆序數 = 前面一個逆序數-所有數中比其小的數+所有數中比其大的數;<br />min = count;<br />}<br />printf("%d/n",min);<br />}<br />return 0;<br />}