poj 2299 逆序数 树状数组 归并
方法一:树状数组
1.树状数组讲解http://www.cnblogs.com/inpeace7/archive/2012/04/11/2441352.html
2.离散化
输入a[i]
i 1 2 3 4 5 6 7
a[i] 50 60 80 90 20 100 50
p[i] 2 3 4 5 1 6 2
把a[i]变为p[i]即为离散化
方法:定义结构体,存储a[i]和i,按照a[i]排序,
p[node[1].data]=1;
int cnt=1;
for(i=1;i<n;i++)
{
if(node[i-1].data=node[i].data) p[node[i].in]=cnt;
else p[node[i].in]=++cnt;
}
1 #include <iostream> 2 #include <algorithm> 3 #include <stdio.h> 4 #include <string.h> 5 using namespace std; 6 7 typedef long long ll; 8 #define lowbit(x) ((x)&(-x)) 9 10 const int maxx=500000; 11 ll tree[maxx+10]; 12 int index[maxx+10]; 13 int n; 14 struct NODE 15 { 16 ll data; 17 int in; 18 }node[maxx+10]; 19 20 int cmp(NODE a,NODE b) 21 { 22 if(a.data!=b.data) return a.data<b.data; 23 else return a.in<b.in; 24 } 25 26 void update(int i,int val) 27 { 28 while(i<=n) 29 { 30 tree[i]+=val; 31 i+=lowbit(i); 32 } 33 } 34 35 ll getsum(int i) 36 { 37 ll sum=0; 38 while(i>0) 39 { 40 sum+=tree[i]; 41 i-=lowbit(i); 42 } 43 44 return sum; 45 } 46 47 int main() 48 { 49 int i,cnt; 50 ll ans; 51 // freopen("in.txt","r",stdin); 52 while(scanf("%d",&n)!=EOF) 53 { 54 if(n==0) break; 55 ans=0; 56 memset(tree,0,sizeof(tree)); 57 for(i=1;i<=n;i++){scanf("%lld",&node[i].data);node[i].in=i;} 58 sort(node+1,node+n+1,cmp); 59 index[node[1].in]=1; 60 cnt=1; 61 for(i=2;i<=n;i++) 62 { 63 if(node[i].data==node[i-1].data) index[node[i].in]=cnt; 64 else index[node[i].in]=++cnt; 65 //cout<<"**"<<index[node[i].in]<<" "<<node[i].data<<endl; 66 } 67 for(i=1;i<=n;i++) 68 { 69 update(index[i],1); 70 ans+=(ll)(i-getsum(index[i])); 71 } 72 printf("%lld\n",ans); 73 } 74 75 return 0; 76 }
方法二:归并
1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 typedef long long ll; 6 const int maxx= 500000,inf=0x7fffffff; 7 ll L[maxx/2+10],R[maxx/2+10],a[maxx+10],cnt; 8 9 void mergee(int p,int q,int r) 10 { 11 int n1=q-p+1,n2=r-q,i,j,k; 12 for(i=0;i<n1;i++) L[i]=a[p+i]; 13 for(i=0;i<n2;i++) R[i]=a[q+i+1]; 14 i=0,j=0,L[n1]=inf,R[n2]=inf; 15 for(k=p;k<=r;k++) 16 { 17 if(L[i]<=R[j]){a[k]=L[i];i++;} 18 else {a[k]=R[j];j++;cnt=cnt+n1-i;} 19 } 20 } 21 22 void mergesort(int p,int r) 23 { 24 if(p<r) 25 { 26 int q=(p+r)/2; 27 mergesort(p,q); 28 mergesort(q+1,r); 29 mergee(p,q,r); 30 } 31 } 32 int main() 33 { 34 int n,i; 35 freopen("in.txt","r",stdin); 36 while(scanf("%d",&n)!=EOF) 37 { 38 if(n==0) break; 39 cnt=0; 40 for(i=0;i<n;i++)scanf("%lld",a+i); 41 mergesort(0,n-1); 42 printf("%lld\n",cnt); 43 } 44 return 0; 45 }