hdu 1394 线段树版~~~@ !@

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

你可能感兴趣的:(struct,tree,百度,search,insert)