快排求TopK,归并求逆序对模板

TopK

# 前K小 
int quicksort(vector<int>& arr,int left,int right)
    {
       int tmp = arr[left];
       while(left < right)
       {
           while(left < right && arr[right] > tmp) right--;
           arr[left] = arr[right];
           while(left < right && arr[left] <= tmp) left++;
           arr[right] = arr[left];
       }
       arr[left] = tmp;
       return left;
    }


    void TopK(vector<int>& arr,int l,int r,int k)
    {
        int index = quicksort(arr,l,r);
        int num = index-l+1;
        if(num == k) return;
        if(num < k ) TopK(arr,index+1,r,k-num);
        else TopK(arr,l,index-1,k);
    }

#前k大
int partition(int A[], int left, int right)
{
    int temp = A[left];
    while(left<right)
    {
        while(left<right && A[right]>temp) right--;
        A[left] =  A[right];
        while(left<right && A[left]<=temp) left++;
        A[right] = A[left];
    }
    A[left] = temp;
    return left;
}

int Topk_Max(int A[], int left, int right, int k)
{
    if(left==right) return A[left];
    int p = partition(A, left, right);
    if(k==p-left+1) return A[p];
    if(k<p-left+1) return KstMax(A, left, p-1, k);
    else return KstMax(A, p+1, right, k);
}

逆序对个数

#include <bits/stdc++.h>
using namespace std;
//在某个时候,左区间:  5 6 7  下标为i
//           右区间:  1 2 9  下标为j
//          
//这个时候我们进行合并:
//step 1:由于 5>1,所以产生了逆序对,这里,我们发现,左区间所有还没有被合并的数都比 1 大,所以1与左区间所有元素共产生了 3 个逆序对(即tot_numleft-i+1对),统计答案并合并 1 
//step 2:由于 5>2,由上产生了3对逆序对,统计答案并合并 2
//step 3:由于 5<9, 没有逆序对产生,右区间下标 j++
//step 4:由于 6<9, 没有逆序对产生,右区间下标 j++
//step 5:由于 7<9, 没有逆序对产生,右区间下标 j++
//step 6:由于右区间已经结束,正常执行合并左区间剩余,结束

const int maxn = 5e5+10;
int a[maxn], temp[maxn];
long long res = 0;

void mergeSort(int l, int r)
{
    if(l==r) return;
    int mid = (l+r)/2, i=l, j=mid+1, index=l;
    mergeSort(l, mid);
    mergeSort(mid+1, r);
    while(i<=mid && j<=r)
    {
        if(a[i]<=a[j]) temp[index++]=a[i++];
        else
        {
            temp[index++] = a[j++];
            res += mid-i+1;
        }
    }
    while(i<=mid) temp[index++] = a[i++];
    while(j<=r) temp[index++] = a[j++];
    for (int i = l; i <= r; ++i)
    {
        a[i] = temp[i];
    }
}
int main(int argc, char const *argv[])
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &a[i]);
    }
    mergeSort(0, n-1);
    printf("%lld
", res);
    return 0;
}
原文地址:https://www.cnblogs.com/z1141000271/p/12735941.html