Median Count 51Nod - 1682 (thought questions, detailed explanation)

https://cn.vjudge.net/problem/51Nod-1682

The median is defined as the number in the middle after all values ​​are sorted from small to large. If there are an even number of values, the average of the two middlemost values ​​is usually taken as the median.

Now that there are n numbers, each of which is unique, find out how many intervals each number contains is the median.


Input the first line of a number n (n<=8000) 
the second line of n numbers, 0<=each number<=10^9OutputN number, which in turn indicates how much the ith number is the median in the interval containing it number. Sample Input
5
1 2 3 4 5
Sample Output
1 2 3 2 1

Question meaning: Chinese title meaning will not be explained.

Idea: Number the numbers first, and then sort the structures with the numbers.

For example: 13

x : 5 8 7 11 2 13 3 6 12 9 4 1
10 12 13
x: 1 2 3 4 5 6 7 8 9 10 11 12 13

id:12  5  7 11  1  8  3  2  10  13  4   9   6

Start with the small number of x, and traverse from the small to the large;

int b[N]; b[i] indicates whether the i-th position has already appeared, 1 if it has appeared, 0 if it is appearing, and -1 if it does not appear; mem(b,-1); is convenient for initialization. (The following operations are for positions, and the relative size of the sorted numbers is determined by the value of the b array)

Now start traversing from the smallest number, the smallest number is at the position of 12

 1   2  3  4   5   6  7  8  9  10  11 12  13
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1   0   -1 

Now only 12 of this position has appeared. How do I calculate the median if the number in position 12 is calculated. (First understand the b array, 0, 1, -1)

Now the number in position 5 has appeared and the number in position 12 has appeared

 1   2  3  4   5   6  7  8  9  10  11 12  13

-1 -1 -1 -1  0  -1 -1 -1 -1 -1  -1    1   -1 

The position that has appeared is written as 1, the position that does not appear is still -1, and the position that is being calculated is 0

The process in the middle will not be written in detail, and jump directly to the time when position 8 appears (the positions 12, 5, 7, 11, 1 have already appeared)

 1   2  3  4   5   6  7  8  9  10  11 12  13

 1 -1 -1 -1   1 -1   1  0 -1 -1    1   1   -1 

Now calculate the number of intervals in which the number at position 8 is the median: first, the interval must contain the position of 8, and the interval is continuous, and the number at the position of 8 is the median. First, think about how to ensure the selected interval. The number at the position of 8 is the median, and the number smaller than this position is as much as the number larger than this position.

What is the performance of a number smaller than this position, that is, the current b array value is 1, and the larger value is -1, then how to express the same number, that is not the number of 1 and the number of -1. A lot. The premise is that there is an interval containing position 8, and there are as many 1s and -1s. Then you find the sum of the first n items of the b array and look again.

   1   2  3  4   5   6  7         8  9  10  11 12  13

   1 -1 -1 -1   1 -1   1        0 -1  -1   1   1   -1 

0 1  0  -1 -2  -1 -2 -1      -1 -2 -3  -2 -1  -2

Now divide these numbers into two parts, the latter -2 and the former -2 are equal, then subtract the former value from the latter to 0. What does 0 stand for?

For example, two underlined two -2, subtract the previous one from the latter, then it means the interval [5,13]. Does this interval meet the meaning of the question? First, it satisfies the position 8, and it is a interval. Then the sum of the b arrays of the combined interval is 0, and consider whether the number at position 8 is the median. Because the sum of the b arrays of the interval is 0, then the number of 1s is as many as the number of -1s. If it is 1, it means a number less than position 8, and -1 means a position greater than the number 8. Then such an interval is consistent. Then you only need to count how many times the numbers after 8 (including the position of 8) appear in the front. For example, -1 and -1 in position 8 appear 3 times before, then it means that there are 3 intervals that satisfy the meaning of the question with 8 as the endpoint of the right interval ([4,8][6,8][8,8]) , the -1 below the position 12 also means that there are the same 3 (4[4,12][6,12][8,12]), so use the bucket sort to store how many such numbers appear before the position 8 That's it. Don't forget that the sum of the first 0 items in the b array is 0.

(Note: The numbers for bucket sorting have negative numbers, so add 8000 to all the numbers to be bucket sorted, and it will not be negative.)

Each number only needs to be calculated once o(n), so the total complexity is n^2.

Inability to complain: During the game, I still didn't have a clear idea, and confused the position with the number, which resulted in an additional restriction (superfluous), which is a pity. The code during the game is AC after a few lines are deleted. QAQ

Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include<list>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x3f3f3f3f
typedef long long ll;
const int N=16000+10;//The bucket row array should be doubled
struct node
{
    int x,id;
} a[N];
struct hpc
{
    bool operator()(node a,node b)
    {
        return a.x<b.x;
    }
};
int b[N];
int c[N];
int ans[N];
intmain()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i].x);
        a[i].id=i;
    }
    sort(a+1,a+1+n,hpc());
    mem(b,-1);//initialized to -1, indicating a position that has not appeared
    mem(ans,0);//Save the answer
    for(int i=1; i<=n; i++)//traverse the array from small to large
    {
        int id=a[i].id;//The position of the current number
        b[id]=0;//The current position is assigned to 0
        int sum=8000;//Count the sum of the first n items of the b array
        mem(c,0);//Bucket sorted array initialization
        c[8000]=1;//The first sum also appears once
        for(int j=1; j<id; j++)//sum that appeared in the previous bucket row
        {
            sum+=b[j];
            c[i]++;
        }
        for(int j=id; j<=n; j++)//Use the c array arranged in the previous bucket later
        {
            sum+=b[j];
            ans[id]+=c[sum];//This answer is the answer of the location id.
        }
        b[id]=1;//After the calculation, the representation will become 1;
    }
    for(int i=1; i<=n; i++)
    {
        if(i!=1) printf(" ");
        printf("%d",ans[i]);
    }
    printf("\n");
    return 0;
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325971155&siteId=291194637