SJTU寻找数列最小元素

寻找数列最小元素

【问题描述】

给定一个长度为n的数列,现声明两种操作。

第一种操作add,将数列的第i个元素的值增加x

第二种操作query,询问此时数列中最小的元素是哪个。
【输入形式】

第一行为一正整数n(<=500000)表示数列长度。

第二行为n个整数,表示数列初始元素。

第三行为一个正整数q(<=1000000),表示操作数。

接下来q行,每行描述一种操作:

add i x

表示数列第i(1<=i<=n)个元素增加x(-1000<=x<=1000)。

query

输出此时数列中最小元素所在位置,以及最小值。多个最小值输出下标最小的那个。
【输出形式】

对于每个query操作,输出一行,包含两个数字,第一个数字为最小值所在下标,第二个数字表示最小值。
【样例输入】

5
1 2 3 4 5
5
query
add 1 2
query
add 2 2
query
【样例输出】

1 1
2 2
1 3

【样例说明】

第一次query时数列为1,2,3,4,5,输出1,1

第二次query时数列为3,2,3,4,5,输出2,2

第三次query时数列为3,4,3,4,5,输出1,3

#include <iostream>
#include <string>
using namespace std;

class elem {
public:
    int index;
    int num;
    elem(int i = 0, int n = 0):index(i), num(n){}
    bool operator<(const elem& e) const{
        if (this->num == e.num)
            return this->index < e.index;
        return this->num < e.num;
    }
    bool operator>(const elem& e) const{
        if (this->num == e.num)
            return this->index > e.index;
        return this->num > e.num;
    }
};
    
class priorityQueue {
public:
//    priorityQueue(int capacity = 100);
    priorityQueue(const elem data[], int size);
    ~priorityQueue();
//    bool isEmpty() const;
//    void enQueue(const elem & x);
//    elem deQueue();
    elem getHead() const;
//    int size() const { return currentSize; }
    void addIndexElem(int index, int num);
    void printArr();
    void printArrIndex();
private:
    int currentSize;
    elem *array;
    int *arr_index; // map original index to array index
    int maxSize;
    void doubleSpace() ;
    void buildHeap() ;
    void percolateDown(int hole);
    void percolateUp(int hole);
};

//priorityQueue::priorityQueue(int capacity)
//{
//    array = new elem[capacity];
//    maxSize = capacity;
//    currentSize = 0;
//}

    priorityQueue::priorityQueue(const elem* items, int size) :maxSize(size + 10), currentSize(size){
        array = new elem[maxSize];
        arr_index = new int[size];
        for (int i = 0; i < currentSize; ++i){
            array[i + 1] = items[i];
            arr_index[i] = i + 1;
        }
        buildHeap();
    }

    priorityQueue::~priorityQueue(){
        delete [] array;
        delete [] arr_index;
    }

//bool priorityQueue::isEmpty()const
//{
//    return currentSize == 0;
//}

    elem priorityQueue::getHead()const{
        return array[1];
    }

//void priorityQueue::enQueue(const elem& x)
//{
//    if (currentSize == maxSize - 1) doubleSpace();
//    int hole = ++currentSize;
//    for (; hole > 1 && x < array[hole / 2]; hole /= 2)
//        array[hole] = array[hole / 2];
//    array[hole] = x;
//}

//void priorityQueue::doubleSpace()
//{
//    elem* tmp = array;
//    maxSize *= 2;
//    array = new elem[maxSize];
//    for (int i = 0; i <= currentSize; ++i)
//        array[i] = tmp[i];
//    delete[]tmp;
//}

//elem priorityQueue::deQueue()
//{
//    elem minItem;
//    minItem = array[1];
//    array[1] = array[currentSize--];
//    percolateDown(1);
//    return minItem;
//}

    void priorityQueue::percolateDown(int hole){
        int child;
        elem tmp = array[hole];
        for (; hole * 2 <= currentSize; hole = child)
        {
            child = hole * 2;
            if (child != currentSize && array[child + 1] < array[child])
                child++;
            if (array[child] < tmp) {
                array[hole] = array[child];
                arr_index[array[child].index] = hole;
            }
            else break;
        }
        array[hole] = tmp;
        arr_index[tmp.index] = hole;
    }

    
    
    void priorityQueue::percolateUp(int hole){
        int parent;
        elem tmp = array[hole];
        while (hole > 1) {
            parent = hole / 2;
            if (array[parent] > tmp) {
                array[hole] = array[parent];
                arr_index[array[parent].index] = hole;
                hole = parent;
            }
            else break;
        }
        array[hole] = tmp;
        arr_index[tmp.index] = hole;
    }
    
    void priorityQueue::printArr(){
        for (int i = 1; i <= currentSize; i++) {
            cout << "array["<< i << "] = "
                 << '(' << array[i].index << ", " << array[i].num << ')'<< endl;
        }
    }
    
    void priorityQueue::printArrIndex(){
        for (int i = 0; i < currentSize; i++) {
            cout << "arr_index["<< i << "] = " << arr_index[i] << endl;
        }
    }

    
    void priorityQueue::buildHeap(){
        for (int i = currentSize / 2; i > 0; i--)
            percolateDown(i);
    }
    
    void priorityQueue::addIndexElem(int index, int num){
        if (num == 0) return;
        int i = arr_index[index];
        array[i].num += num;
        if (num > 0)
            percolateDown(i);
        else if (num < 0)
            percolateUp(i);
    }

int main()
{
    int n, num;
    cin >> n;
    elem* a = new elem[n];
    for (int i = 0; i < n; i++) {
        scanf("%d", &num);
        a[i].index = i;
        a[i].num = num;
    }
    priorityQueue q(a, n);
    cin >> num;
    while (num--) {
        string s;
        cin >> s;
        if (s == "query"){
            elem min_elem = q.getHead();
            printf("%d %d\n", min_elem.index + 1, min_elem.num);
        }
        else if (s == "add") {
            int index;
            int num;
            scanf("%d%d", &index, &num);
            q.addIndexElem(index - 1, num);
        }
//        q.printArr();
//        q.printArrIndex();
    }
    return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值