[2017.7.7 popularization] ultimate number

Posted by phpvn.org on Thu, 09 Apr 2020 18:39:01 +0200

subject

Title Description

Given a sequence a of length n, we try to find the ultimate number x of each prefix of sequence a

Minimum, try to find the ultimate number t (if there are multiple ultimate numbers t, just output the smallest one)

input
The first line is an integer n, the second line is an integer n, separated by spaces

output
Output an integer line by line, that is, the ultimate number t

The main idea of the topic

Because the problem is more difficult to understand, in fact, it is to find out the median of multiple medians, and then find the median of multiple medians

Solving problems

For 20% of the data: direct violence

For 40% of the data: obviously, for the ultimate number of a sequence, it must be the median of the sequence, so you can use fast sorting to achieve O()

For 100% data: find the median, use heap,

We maintain two heaps, a large root heap and a small root heap. At present, when we add one number at a time, we must ensure that the number of small root heap is greater than or equal to the number of large root heap. That is to say, when we add the number for the first time, we must put it in the minimum heap.

Secondly, we also need to ensure that each value in the small root heap must be greater than or equal to the maximum value in the large root heap.

In addition, if the current number of large root heap is smaller than that of small root heap, we need to add the next number to the large root heap, and vice versa.

When we add a number, there are two special cases:

Set the number of joins as X. if x is larger than the top of the small root heap when you want to join the large root heap, perform the temp1 operation.

On the contrary, if x is smaller than the top of the big root heap when adding to the small root heap, then temp2 operation is performed.

temp1: put x in the small root heap, and put the top of the small root heap into the large root heap, and maintain the two properties.
temp2: put x in the big root heap, and put the top of the big root heap into the small root heap, and maintain the two properties.

What we are looking for is the top of every small pile ..

Code

#include<cstdio>
#include<algorithm>
using namespace std; 
int n,u,num,nuu,a[1000001],b[1000001],d[1000001]; 

void upa(int x)//Because there are two root heaps, which are easy to operate, two up and down are defined
 {
    while (x>1&&a[x]<a[x/2]) swap(a[x],a[x/2]),x/=2; 
 }

 void downa(int x) //Heap heap
 {
    int y; 
    while ((a[x*2]<a[x]&&x*2<=nuu)||(a[x*2+1]<a[x]&&x*2+1<=nuu))
    {
        y=x*2; 
        if (a[y+1]<a[y]&&y+1<=nuu) y++; 
        swap(a[x],a[y]);
        x=y; 
    }
 }

void upb(int x)
 {
    while (x>1&&b[x]>b[x/2]) swap(b[x],b[x/2]),x/=2; 
 }

 void downb(int x)//Big root pile
 {
    int y; 
    while ((b[x*2]>b[x]&&x*2<=num)||(b[x*2+1]>b[x]&&x*2+1<=num))
    {
        y=x*2; 
        if (b[y+1]>b[y]&&y+1<=num) y++; 
        swap(b[x],b[y]); 
        x=y; 
    }
 }

int main()
{
    //freopen("c.in","r",stdin);
    //freopen("c.out","w",stdout);
    scanf("%d",&n); 
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&u); 
        if (nuu<=num) //If the length of the small root heap is less than or equal to the length of the large root heap, put it in the small root heap
        {
           if (u<b[1]) {//If u is smaller than the top of the big root heap, exchange a[++nuu] and b[1] and maintain two heaps
            a[++nuu]=b[1]; 
            upa(nuu); 
            downa(1); 
            b[1]=u; 
            downb(1); 
          } else {//Normal processing
             a[++nuu]=u; upa(nuu); downa(1);
          } 
        } else //Or put it in the big pile
        {
          if (u>a[1]) {//If u is larger than the top of the small root heap, exchange the original b[++num] and a[1] and maintain the two heaps
             b[++num]=a[1]; 
             upb(num); 
             downb(1); 
             a[1]=u; 
             downa(1); 
          } else {//Normal processing
             b[++num]=u; upb(num); downb(1);
          }
        }
        d[i]=a[1]; //Median
    }
    sort(d+1,d+n+1); 
    printf("%d",d[n/2]);//Take the median of multiple median
    return 0; 
}

Topics: less