• 快排求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;
    }
  • 相关阅读:
    ios实例开发精品源码文章推荐
    Citrix 服务器虚拟化之二十七 XenApp6.5发布服务器桌面
    TOJ3651确定比赛名次
    TOJ3649欧拉回路
    强连通分量(LRJ训练指南)
    汉语-词语-体谅:百科
    汉语-词语-关心:百科
    汉语-词语-懒惰:百科
    汉语-词语-平静:百科
    汉语-词语-遗迹:百科
  • 原文地址:https://www.cnblogs.com/z1141000271/p/12735941.html
Copyright © 2020-2023  润新知