hdu

http://acm.hdu.edu.cn/showproblem.php?pid=1394

很基础的线段树.

先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum就是当前数的逆序数.

这样查询完之后得到初始数列的逆序数,要求得所有序列的最小逆序数,还需要循环一次.

设初始序列abcde中逆序数为k,小于a的个数是t-1那么大于a的个数就是n-t,当把a左移一位,原来比a大的都变成了a的逆序对,即逆序数增加了n-t,但是原来比a小的数都变成了顺序,

因此逆序数减少了t-1,所以新的序列的逆序数为k+=n-t-t+1;

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <vector>
  5 #include <cstring>
  6 #include <string>
  7 #include <algorithm>
  8 #include <string>
  9 #include <set>
 10 #include <functional>
 11 #include <numeric>
 12 #include <sstream>
 13 #include <stack>
 14 #include <map>
 15 #include <queue>
 16 #include <deque>
 17 //#pragma comment(linker, "/STACK:102400000,102400000")
 18 #define CL(arr, val)    memset(arr, val, sizeof(arr))
 19 
 20 #define ll long long
 21 #define INF 0x7f7f7f7f
 22 #define lc l,m,rt<<1
 23 #define rc m + 1,r,rt<<1|1
 24 #define pi acos(-1.0)
 25 
 26 #define L(x)    (x) << 1
 27 #define R(x)    (x) << 1 | 1
 28 #define MID(l, r)   (l + r) >> 1
 29 #define Min(x, y)   (x) < (y) ? (x) : (y)
 30 #define Max(x, y)   (x) < (y) ? (y) : (x)
 31 #define E(x)        (1 << (x))
 32 #define iabs(x)     (x) < 0 ? -(x) : (x)
 33 #define OUT(x)  printf("%I64d
", x)
 34 #define lowbit(x)   (x)&(-x)
 35 #define Read()  freopen("a.txt", "r", stdin)
 36 #define Write() freopen("b.txt", "w", stdout);
 37 #define maxn 5010
 38 #define maxv 50010
 39 #define mod 1000000000
 40 using namespace std;
 41 #define lson l,m,rt<<1
 42 #define rson m+1,r,rt<<1|1
 43 
 44 int sum[maxn<<2];
 45 
 46 void PushUP(int rt)
 47 {
 48     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 49 }
 50 
 51 void build(int l,int r,int rt)
 52 {
 53     sum[rt]=0;
 54     if(l==r) return;
 55     int m=(l+r)>>1;
 56     build(lson);
 57     build(rson);
 58 }
 59 
 60 void update(int p,int l,int r,int rt)
 61 {
 62     if(l==r)
 63     {
 64         sum[rt]++;
 65         return;
 66     }
 67     int m=(l+r)>>1;
 68     if(p<=m) update(p,lson);
 69     else update(p,rson);
 70     PushUP(rt);
 71 }
 72 
 73 int query(int L,int R,int l,int r,int rt)
 74 {
 75     if(L<=l&&r<=R)
 76     {
 77         return sum[rt];
 78     }
 79     int m=(l+r)>>1;
 80     int ret=0;
 81     if(L<=m) ret+=query(L,R,lson);
 82     if(R>m) ret+=query(L,R,rson);
 83     return ret;
 84 }
 85 
 86 int x[maxn];
 87 int main()
 88 {
 89     //Read();
 90     int n;
 91     while(~scanf("%d",&n))
 92     {
 93         build(0,n-1,1);
 94         int ans=0;
 95         for(int i=0;i<n;i++)
 96         {
 97             scanf("%d",&x[i]);
 98             ans+=query(x[i],n-1,0,n-1,1);
 99             update(x[i],0,n-1,1);
100         }
101         int ret=ans;
102         for(int i=0;i<n;i++)
103         {
104             ans+=n-x[i]-x[i]-1;
105             ret=min(ret,ans);
106         }
107         printf("%d
",ret);
108     }
109     return 0;
110 }
原文地址:https://www.cnblogs.com/nowandforever/p/4572183.html