HDU 1394Minimum Inversion Number
题意:很水的用线段树求逆序对的题,时间复杂度在nlogn适合初学者,数据较小不用离散化,直接敲即可;
#include<algorithm> #include<iostream> #include<map> #include<set> #include<vector> #include<stack> #include<queue> #include<cstring> #include<cstdio> #define N 10005 #define INF 0x3f3f3f3f using namespace std; typedef struct node{ int x;int y;int date; }node; node a[5005*4]; void built(int root,int first,int end){ if(first==end){ a[root].x=first;a[root].y=end;a[root].date=0; return ; } int mid=(first+end)/2; built(root*2,first,mid); built(root*2+1,mid+1,end); a[root].x=a[root*2].x;a[root].y=a[root*2+1].y;a[root].date=0; } void U(int root,int first,int end,int e){ if(first==end){ a[root].date=1; return ; } int mid=(first+end)/2; if(e<=mid) U(root*2,first,mid,e); else U(root*2+1,mid+1,end,e); a[root].date=a[root*2].date+a[root*2+1].date; } int sum=0; void Q(int root,int first,int end,int l,int r){ if(first>=l&&end<=r){ sum+=a[root].date; return ; } int mid=(first+end)/2; if(l<=mid) Q(root*2,first,mid,l,r); if(r>mid) Q(root*2+1,mid+1,end,l,r); } int b[5005]; int c[5005]; int main(){ int n; while(scanf("%d",&n)==1){ for(int i=1;i<=n;i++){ scanf("%d",&b[i]); } int ans=0; built(1,0,n-1); for(int i=1;i<=n;i++){ sum=0; if(b[i]==0){ U(1,0,n-1,0); } else{ Q(1,0,n-1,0,b[i]-1); ans+=(b[i]-sum); U(1,0,n-1,b[i]); } } c[1]=ans; //cout<<ans<<endl; for(int i=2;i<=n;i++){ c[i]=c[i-1]-b[i-1]-b[i-1]+n-1; } int p=INF; for(int i=1;i<=n;i++){ p=min(p,c[i]); } printf("%d\n",p); } return 0; }