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\n", 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\n",ret); 108 } 109 return 0; 110 }
时间: 2024-10-23 08:33:48