【洛谷刷题】--分治思想-求逆序对

【洛谷刷题】--分治思想-求逆序对_第1张图片

 可用归并排序和树状数组求解:

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,是一种稳定的排序算法,时间复杂度O(nlogn),该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

【洛谷刷题】--分治思想-求逆序对_第2张图片

 【洛谷刷题】--分治思想-求逆序对_第3张图片

 归并排序用到了二分的思想,在排序过程中如果a[i]<=a[j]就不会产生逆序对,如果a[i]>a[j]就会产生mid−i+1个逆序对,因为做归排的时候l~mid和mid+1~r都是已经排好序的所以如果a[i]>a[j]那么a[i+1]~a[mid]也就都大于a[j]

#include
#include
using namespace std;
int n,a[500010],c[500010];
long long ans;

void msort(int b,int e)//归并排序
{
    if(b==e)  
        return;
    int mid=(b+e)/2,i=b,j=mid+1,k=b;
    msort(b,mid),msort(mid+1,e);
    while(i<=mid&&j<=e)
        if(a[i]<=a[j])
            c[k++]=a[i++];
        else
            c[k++]=a[j++],ans+=mid-i+1;//统计答案
    while(i<=mid)
        c[k++]=a[i++];
    while(j<=e)
        c[k++]=a[j++];
    for(int l=b;l<=e;l++)
        a[l]=c[l];
} 

int main()
{
    cin>>n; 
    for(int i=1;i<=n;i++)
        cin>>a[i];
    msort(1,n);
    cout<

参考:1.https://www.luogu.org/problemnew/solution/P1908?page=2

2.https://www.cnblogs.com/cytus/p/7811856.html

你可能感兴趣的:(#,洛谷刷题)