之前写过树状数组的,再用线段树写一下~~~
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 using namespace std; 8 #define lp (p << 1) 9 #define rp (p << 1 | 1) 10 #define getmid(l,r) (l + (r - l) / 2) 11 12 const int maxn = 50005; 13 struct node{ 14 int l,r,s; 15 }t[4*maxn]; 16 17 int a[maxn],n; 18 19 int calc(int a,int b) { return a+b; } 20 21 void Push_up(int p){ 22 t[p].s = calc(t[lp].s,t[rp].s); 23 } 24 25 void Build_tree(int p,int l,int r){ 26 t[p].l = l; 27 t[p].r = r; 28 if(l == r){ t[p].s = 0;return;} 29 int mid = getmid(l,r); 30 Build_tree(lp,l,mid); 31 Build_tree(rp,mid+1,r); 32 Push_up(p); 33 } 34 35 void update(int p,int s,int w){//给s点加上w 36 if(t[p].l == t[p].r) { 37 t[p].s += w; 38 return; 39 } 40 int mid = getmid(t[p].l,t[p].r); 41 if(s <= mid) update(lp,s,w); 42 else update(rp,s,w); 43 Push_up(p); 44 } 45 46 int sum(int p,int l,int r){ 47 if(t[p].l == l && t[p].r == r) return t[p].s; 48 49 int mid = getmid(t[p].l,t[p].r); 50 if(r <= mid) return sum(lp,l,r); 51 else if(mid < l) return sum(rp,l,r); 52 else return calc(sum(lp,l,mid),sum(rp,mid+1,r)); 53 } 54 55 int main(){ 56 int T; 57 while(scanf("%d",&n) != EOF){ 58 for(int i = 1;i <= n;i++) scanf("%d",&a[i]),a[i]; 59 Build_tree(1,1,n); 60 61 int ans = 0; 62 for(int i = 1;i <= n;i++){ 63 ans += sum(1,a[i]+1,n);update(1,a[i],1); 64 // printf("ans = %d ",ans); 65 } 66 67 int res = ans; 68 for(int i = 1;i <= n;i++){ 69 ans += n-2*a[i] - 1; 70 res = min(res,ans); 71 // printf("res = %d ",res); 72 } 73 printf("%d ",res); 74 } 75 return 0; 76 }