力扣OJ 剑指 Offer 51. 数组中的逆序对(离散化+sum型线段树)

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

 

示例 1:

输入: [7,5,6,4]
输出: 5
 

限制:

0 <= 数组长度 <= 50000

 

#include 
//拓展数据域,加上id
template
vector>expand(vectorv)
{
    vector>ans;
    ans.resize(v.size());
    for (int i = 0; i < v.size(); i++)ans[i].first = v[i], ans[i].second = i;
    return ans;
}
//提取pair数组的first
template
vector fdraw(vector>v)
{
    vectorans(v.size());
    for (int i = 0; i < v.size(); i++)ans[i] = v[i].first;
    return ans;
}
//提取pair数组的second
template
vector fdraw2(vector>v)
{
    vectorans(v.size());
    for (int i = 0; i < v.size(); i++)ans[i] = v[i].second;
    return ans;
}
//给vector拓展,加上id并排序
template
bool cmp(pair x, pair y)
{
    if (x.first == y.first)return x.second < y.second;
    return x.first < y.first;
}
template
vector> sortWithId(vectorv)
{
    vector>ans = expand(v);
    sort(ans.begin(), ans.end(),cmp);
    return ans;
}
//排序后数组中的每个数的原ID,输入8 5 6 7,输出1 2 3 0,也可以直接求逆置换
template
vector sortId(vectorv)
{
    return fdraw2(sortWithId(v));
}
//每个数在排序后的数组中的ID,输入8 5 6 7,输出3 0 1 2
template
vector sortId2(vectorv)
{
    return sortId(sortId(v));
}


int num[100001], sum[400001];
const int p = 1000000007;

void update(int key, int low, int high, int uplace)
{
    if (low == high)
    {
        sum[key] = num[low];
        return;
    }
    int mid = (low + high) / 2;
    if (uplace <= mid)update(key * 2, low, mid, uplace);
    else update(key * 2 + 1, mid + 1, high, uplace);
    sum[key] = (sum[key * 2] + sum[key * 2 + 1]) % p;
}

int query(int key, int low, int high, int x, int y)
{
    if (low == x && high == y)return sum[key];
    int mid = (low + high) / 2;
    if (mid < x)return query(key * 2 + 1, mid + 1, high, x, y);
    if (mid >= y)return query(key * 2, low, mid, x, y);
    return (query(key * 2, low, mid, x, mid) + query(key * 2 + 1, mid + 1, high, mid + 1, y)) % p;
}

class Solution {
public:
    int reversePairs(vector& nums) {
        memset(num, 0, sizeof(num));
        memset(sum, 0, sizeof(sum));
        vectorr = sortId2(nums);
        int ans = 0, len = nums.size();
        for (int i = 0; i < r.size(); i++)
        {
            ans += query(1, 1, len, r[i] + 1, len);
            num[r[i] + 1] = 1;
            update(1, 1, len, r[i] + 1);
        }
        return ans;
    }
};

 

你可能感兴趣的:(new)