pat Grado A 1057 Consulta en línea / consulta dinámica, espacio para el tiempo

Consultando el M-ésimo número más pequeño en la matriz desordenada, insertando y eliminando continuamente durante la consulta, el costo de ordenar cada vez que la consulta es demasiado grande.
Tome el valor máximo posible maxn como rango, divida los números en grupos ceil (sqrt (maxn)), el número de piso (sqrt (maxn)) en cada grupo, y configure dos matrices, una cuenta el número de veces cada una aparece el número, el otro Cuente el número de números en cada grupo.
Al realizar una consulta, primero determine en qué bloque se encuentra y luego busque el bloque M en ese bloque.

#include <cstdio>
#include <stack>
#include <cstring>

using namespace std;

const int maxn = 100001;
const int blk = 317;
const int blk_size = 316;
int N;

stack<int> s;
int num_count[maxn]={
    
    }; //每个数的个数
int blk_count[blk]={
    
    }; //每个块中数的个数

int findMedian();

int main(){
    
    
    scanf("%d", &N);
    while(N--){
    
    
        char command[15];
        scanf("%s", command);
        if(strcmp(command, "Push")==0){
    
    
            int v;
            scanf("%d", &v);
            s.push(v);
            num_count[v]++;
            blk_count[v/blk_size]++;
        }
        else if(strcmp(command, "Pop")==0){
    
    
            if(s.empty()) printf("Invalid\n");
            else{
    
    
                int v = s.top();
                printf("%d\n", v);
                s.pop();
                num_count[v]--;
                blk_count[v/blk_size]--;
            }
        }
        else{
    
    
            if(s.empty()) printf("Invalid\n");
            else printf("%d\n", findMedian());
        }
    }

    return 0;
}

int findMedian(){
    
    
    int n = s.size();
    int M = (n%2==0)?(n/2):((n+1)/2);
    int sum = 0;
    for(int b=0; b<blk; b++){
    
    
        if(sum+blk_count[b]<M){
    
    
            sum += blk_count[b];
            continue;
        }
        else{
    
    
            for(int i=b*blk_size; i<(b+1)*blk_size; i++){
    
    
                if(sum+num_count[i]<M){
    
    
                    sum += num_count[i];
                    continue;
                }
                else return i;
            }
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/sinat_37517996/article/details/104677272
Recomendado
Clasificación