Luogu p1908 reverse order pair

P1908 reverse order pair

Title Description

TOM cat and JERRY Mouse have been competing recently, but they are all adults. They don't like to play the game of chasing each other anymore. Now they like to play statistics. Recently, TOM old cat looked up something called "reverse order pair" of human class, which is defined as: for a given positive integer sequence, the reverse order pair is AI > AJ and i in the sequence

I / O format

Input format:

The first line, a number n, indicates that there are n numbers in the sequence.

The number of n in the second row represents the given sequence.

Output format:

The number of reverse pairs in a given sequence.

Example of input and output

Input example ා 1:

6
5 4 2 6 3 1

Output sample 1: copy

11

Explain

For 50% of data, n ≤ 2500

For 100% of the data, n ≤ 40000.

----------------–

Train of thought 1

This is a way to compare water:
Let's go through the whole array. For each number in the array, we will scan forward. For each number in front, as long as there is a larger number, sum + +, but the complexity of this method is O (n^2), only over 50% of the data.

int a[];
int sum = 0, n;
for(int i = 1; i <= n; ++i) {
    for(int j = 1; j < i; ++j) {
        if(a[j] > a[i]) sum ++;
    }
}

Train of thought 2

Use merge sort.
The basic idea is to divide a sequence into two parts, know how to divide it into a number, and then sort and merge it.

//Merge sort
int a[];

void msort(int l, int r) {
    if(l == r) return;

    int mid = (l + r) / 2;
    msort(l, mid);
    msort(mid + 1, r);
    int r[] = {0};
    int left = l, right = l + 1, mid, k = l;

    while(left <= mid && right <= r) {
        if(a[i] <= a[j]) {
            r[k] = a[i]; k ++; left ++;
        }
        else {
            r[k] = a[j];k ++; left ++;
        }
    }

    while(left <= mid) {
        r[k] = a[left]; k ++; left ++;
    }

    while(right <= r) {
        r[k] = a[right]; k ++; right ++;

    for(int i = l; i <= r; ++i) {
        a[i] = r[i];
    }
}

However, for this problem, the goal we are looking for is that in an array, the size of the back position is smaller than the previous number, so we just need to add a line of code.

ans += mid - i + 1;//The value of mid - left + 1 is the number of reverse pairs

Attach complete AC code

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e4 + 9;
int a[maxn],r[maxn],ans=0,n;
void msort(int s,int t)//Merge sort
{
    if(s==t) return ;
    int mid=(s+t)/2;
    msort(s,mid);
    msort(mid+1,t);
    int i=s,j=mid+1,k=s;
    while(i<=mid&&j<=t){
        if(a[i]<=a[j])
            r[k]=a[i],k++,i++;
        else{
            r[k]=a[j],k++,j++;
            ans+=mid-i+1;
        }
    }
    while(i<=mid)
        r[k]=a[i],k++,i++;
    while(j<=t)
        r[k]=a[j],k++,j++;
    for(int i=s;i<=t;i++)
        a[i]=r[i];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
        scanf("%d",&a[i]);
    msort(1,n);
    printf("%d\n",ans);
    return 0;
}

Posted by Doyley on Sun, 05 Apr 2020 03:13:20 -0700