HDU1394.Minimum Inversion Number
这个题求最小逆序数,先建一个空的树,然后每输入一个值,就先查询一下,查询之后,更新线段树,然后遍历一遍,每次将第一个数放到最后之后,减少的逆序数为x[i],增加的为n-x[i]-1;
所以该种序列的逆序数为sum+=n-x[i]-x[i]-1。直接遍历的时候找最小值就可以了。
写的脑子有点乱。。。
代码:
1 //c
2 #include<iostream>
3 #include<cstdio>
4 #include<cstring>
5 #include<cmath>
6 #include<algorithm>
7 #include<cstdlib>
8 #include<queue>
9 #include<stack>
10 using namespace std;
11 typedef long long ll;
12 const int inf=0x3f3f3f3f;
13 const double eps=1e-5;
14 const int maxn=5*1e5+10;
15 #define lson l,m,rt<<1
16 #define rson m+1,r,rt<<1|1
17 int sum[maxn<<2],MAX[maxn<<2];
18
19 void PushUp(int rt){
20 sum[rt]=sum[rt<<1]+sum[rt<<1|1];
21 //MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
22 }
23 /*
24 void build(int l,int r,int rt){
25 if(l==r){
26 scanf("%d",&sum[rt]);
27 //scanf("%d",&MAX[rt]);
28 return ;
29 }
30 int m=(l+r)>>1;
31 build(lson);
32 build(rson);
33 PushUp(rt);
34 }
35 */
36 void build(int l,int r,int rt){
37 sum[rt]=0;
38 if(l==r)return ;
39 int m=(l+r)>>1;
40 build(lson);
41 build(rson);
42 }
43 void update(int p,int l,int r,int rt){
44 if(l==r){
45 sum[rt]++;
46 return ;
47 }
48 int m=(l+r)>>1;
49 if(p<=m)update(p,lson);
50 else update(p,rson);
51 PushUp(rt);
52 }
53 /*
54 //单点增减
55 void update(int p,int add,int l,int r,int rt){
56 if(l==r){
57 sum[rt]+=add;
58 return ;
59 }
60 int m=(l+r)>>1;
61 if(p<=m)update(p,add,lson);
62 else update(p,add,rson);
63 PushUp(rt);
64 }
65 */
66 /*
67 //单点更新
68 void update(int p,int sc,int l,int r,int rt){
69 if(l==r){
70 MAX[rt]=sc;
71 return ;
72 }
73 int m=(l+r)>>1;
74 if(p<=m)update(p,sc,lson);
75 else update(p,sc,rson);
76 PushUp(rt);
77 }
78 */
79
80 //区间求和
81 int query(int L,int R,int l,int r,int rt){
82 if(L<=l&&r<=R){
83 return sum[rt];
84 }
85 int m=(l+r)>>1;
86 int ret=0;
87 if(L<=m)ret+=query(L,R,lson);
88 if(R>m) ret+=query(L,R,rson);
89 return ret;
90 }
91
92 /*
93 //区间最值
94 int query(int L,int R,int l,int r,int rt){
95 if(L<=l&&r<=R){
96 return MAX[rt];
97 }
98 int m=(l+r)>>1;
99 int ret=0;
100 if(L<=m)ret=max(ret,query(L,R,lson));
101 if(R>m) ret=max(ret,query(L,R,rson));
102 return ret;
103 }
104 */
105 int x[maxn];
106 int main(){
107 int n;
108 while(~scanf("%d",&n)){
109 build(0,n-1,1);
110 int sum=0;
111 for(int i=0;i<n;i++){
112 scanf("%d",&x[i]);
113 sum+=query(x[i],n-1,0,n-1,1);
114 update(x[i],0,n-1,1);
115 }
116 int ret=sum;
117 for(int i=0;i<n;i++){
118 sum+=n-x[i]-x[i]-1;
119 ret=min(ret,sum);
120 }
121 printf("%d\n",ret);
122 }
123 return 0;
124 }