算法导论归并排序那块的一道思考题:
1.merge的时候统计逆序数的个数。
#include<iostream>
using namespace std;
int a[1000];
int cnt;
int merge(int a[],int p,int q,int z)
{   
    
int l[1000],r[1000];
    l[
0]=q-p+1;
    r[
0]=z-q;
    l[l[
0]+1]=0x7fffffff;
    r[r[
0]+1]=0x7fffffff;
    
int i,j,k;
    
for(i=1;i<=l[0];i++)
    {
        l[i]
=a[p+i-1];
    }
    
for(j=1;j<=r[0];j++)
    {
        r[j]
=a[q+j];
    }
    i
=1;
    j
=1;
    
for(k=p;k<=z;k++)
    {   
        
if(l[i]<=r[j])
            a[k]
=l[i++];
        
else
        {   
            a[k]
=r[j++];
            cnt
+=(l[0]-i+1);
        }
    }
    
return 0;
}
int mergesort(int a[],int p,int q)
{
    
if(p>=q)
        
return 0;
    
else 
    {
        
int mid=(p+q)>>1;
        mergesort(a,p,mid);
        mergesort(a,mid
+1,q);
        merge(a,p,mid,q);
    }
    
return 0;
}

int main()
{   
    
int n;
    
int i;
    printf(
"输入待排序的数字个数:\n"); 
    scanf(
"%d",&n);
    printf(
"输入待排序数组:\n");
    
for(int i=1;i<=n;i++)
        scanf(
"%d",&a[i]);
    printf(
"待排序数组:\n");
    
for(i=1;i<=n;i++)
    {
        printf(
"%d ",a[i]);
    }
    printf(
"\n");
    mergesort(a,
1,n);
    printf(
"已排序数组:\n");
    
for(i=1;i<=n;i++)
    {
        printf(
"%d ",a[i]);
    }
    printf(
"\n逆序数为:");
    printf(
"%d\n",cnt);
    system(
"pause");
    
return 0;
}
2.离散化,扫描原始数列,若已插入某数字,设某数字离散化的位置为t,则t的cnt+1,维护树状数组。每次cnt+1之前之前算一下sum[n]-sum[t](n为离散化后数组中元素的个数),然后插入。
//PKU 2299
#include
<iostream>
#include
<algorithm>
#define N 500010
using namespace std;
int c[N];
int a[N];
int b[N];
int n;
int num=1;
int lowbit(int t)
{
    
return t&(t^(t-1));
}
int getsum(int t)
{
    
int sum=0;
    
for(int i=t;i>0;i-=lowbit(i))
        sum
+=c[i];
    
return sum;
}
void update(int t)
{
    
for(int i=t;i<=num;i+=lowbit(i))
        c[i]
++;
}
int search(int i)
{
    
int mid,l=1,r=num;
    
while(l<=r)
    {
        mid
=(l+r)/2;
        
if(a[mid]==i)
            
return mid;
        
else if(a[mid]>i)
            r
=mid-1;
        
else l=mid+1;
    }
}
int main()
{
    
while(scanf("%d",&n)!=EOF&&n)
    {
        
for(int i=1;i<=n;i++)
        {
            scanf(
"%d",&a[i]);
            b[i]
=a[i];
        }
        num
=1;
        sort(a
+1,a+1+n);
        
for(int i=2;i<=n;i++)
        {
            
if(a[i]!=a[i-1])
                a[
++num]=a[i];
        }

        memset(c,0,sizeof(c));
        
long long sum=0;
        update(search(b[
1]));
        
for(int i=2;i<=n;i++)
        {
            
int t=search(b[i]);
            sum+=getsum(num)-getsum(t);
            update(t);
        }

        printf("%lld\n",sum);
    }
    
}