445 模式寻对

来源:互联网 发布:中秋的数据 编辑:程序博客网 时间:2024/05/14 04:26

模式寻对

时间限制: 1000 ms 内存限制: 65536 kb
总通过人数: 158 总提交人数: 168

概念回顾

逆序对:数列a[0],a[1],a[2]…中的任意两个数a[i],a[j],如果i<j, 并且a[i]>a[j],那么我们就说这两个数构成了一个逆序对。逆序数:一个数列中逆序对的总数。

题目描述

输入一个正整数n,随后给出一个长度为n的整数序列 a[0],a[1],a[2],...,a[n-1] ,再给定多组数组下标范围,求给定序列的逆序数。

输入

多组测试数据(不超过10组),以EOF结尾。

每组测试数据第一行为数组长度n,正整数,代表数组长度,数据范围为0<n<=10000

第二行为n个整数,为数组an,保证数组中每个数在int范围内。

第三行为一个整数t,代表t次查询,0<t<=1000

接下来t行,每行两个数x,y,代表数组下标区间,保证0<=x<=y<=n-1

输出

对于每次查询,输出一行,每行一个数,代表所求逆序数。

具体参见样例。

输入样例

54 8 4 0 030 42 40 2

输出样例

721

提示

使用时间复杂度为 O(n2)O(n2) 的算法会超时。


解析:

归并排序的应用。请在理解归并排序的基础上阅读以下解析。

将数组分为左子数组和又子数组,总逆序数 = 左子数组逆序数 + 又子数组逆序数 + 跨子数组逆序数。左右子数组逆序数都可以通过递归解决,重点在于求出跨子数组逆序数。声明变量ans记录总逆序对数,在归并排序的Merge()函数中修改一个地方即可:当某个左子数组的元素大于又子数组的元素时,这个左子数组元素中比它大的元素也都大于那个又子数组元素,即包括这个左子数组元素在内,共有(q-p+1-i)个元素与那个又子数组元素形成逆序对。因此,ans+=q-p+1-i。随着归并的进行,ans也就算出来了。

代码:

#include<cstdio>#define maxn 10007int ans;int a[maxn],A[maxn];void Merge(int p,int q,int r){    int n1 = q-p+1;    int n2 = r-q;    int L[n1],R[n2];    for(int i = 0; i <= n1; i++)    {        L[i] = A[p+i];    }    for(int i = 0; i <= n2; i++)    {        R[i] = A[i+q+1];    }    int i = 0,j = 0,k = p;    while(i < n1&&j < n2)    {        if(L[i] > R[j])        {            A[k++] = R[j++];            ans += q-p-i+1;        }        else        {            A[k++] = L[i++];        }    }    while(i < n1)    {        A[k++] = L[i++];    }    while(j < n2)    {        A[k++] = R[j++];    }}void Merge_Sort(int p,int r){    if(p < r)    {        int q = (p+r)/2;        Merge_Sort(p,q);        Merge_Sort(q+1,r);        Merge(p,q,r);    }}int main(){    int n;    while(~scanf("%d",&n))    {        for(int i = 0; i < n; i++)        {            scanf("%d",&a[i]);        }        int t;        scanf("%d",&t);        while(t--)        {            int x,y;            scanf("%d%d",&x,&y);            int k = 0;            for(int i = x;i <= y;i++)            {                A[k++] = a[i];            }            ans = 0;            Merge_Sort(0,y-x);            printf("%d\n",ans);        }    }}


原创粉丝点击