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 }

posted on 2012-04-11 19:26  Inpeace7  阅读(293)  评论(0编辑  收藏  举报

导航