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 ",ret); 122 } 123 return 0; 124 }