Cod sursa(job #2625636)

Utilizator bogdan.gusuleacGusuleac Bogdan bogdan.gusuleac Data 6 iunie 2020 03:49:19
Problema Range minimum query Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.08 kb
#include <vector>
#include<tuple>
#include <string.h>
#include <iostream>
#include <fstream>
//#include "nodes.h"
using namespace std;

fstream fin("rmq.in", ios::in);
fstream fout("rmq.out", ios::out);

class node{
protected:
    pair<int, int>range;
    long int minim;

    node *st, *dr;
public:

    node(int stValue, int drValue)
    {
        range = make_pair(stValue, drValue);

        this->minim = 0;

        this->st = nullptr;
        this->dr = nullptr;
    }

    void printNode(ostream &out)
    {
        out<<"Nod cu intervalul ["<<get<0>(range)<<","<<get<1>(range)<<"] , cu maximul: "<<minim<<"\n";
    }

    friend ostream& operator <<(ostream &out, node &n)
    {
        n.printNode(out);
        return out;
    }

    friend class tree;
};

class tree
{
protected:
    node *head;
    vector<int> numbers;
public:
    tree()
    {
        head = nullptr;
    }

    void buildTree()
    {
        head = buildTree(0, numbers.size() - 1, head);
    }
    node* buildTree(int, int, node*);


    void getInput(int, istream&);

    int findMin(int, int, node*);

    void makeQueries(int, istream&, ostream &);

    void printTree()
    {
        printTree(head);
    }

    void printTree(node *temp)
    {
        cout<<*temp;
        if(temp->st != nullptr)
            printTree(temp->st);
        if(temp->dr != nullptr)
            printTree(temp->dr);
        //cout<<*temp<<temp->st<<temp->dr;
    }
};

node* tree::buildTree(int stVal, int drVal, node *temp)
{
    temp = new node(stVal, drVal);

    if(stVal == drVal)
        temp->minim = numbers[stVal];
    else
    {
        ///calculam mijlocul
        int mijl = stVal + (drVal - stVal) / 2;

        temp->st = buildTree(stVal, mijl, temp->st);
        temp->dr = buildTree(mijl + 1, drVal,temp->dr);

        temp->minim = min(temp->st->minim, temp->dr->minim);
    }

    return temp;
}

int tree::findMin(int a, int b, node *temp)
{
    int stVal = temp->range.first;
    int drVal = temp->range.second;

    if(a == stVal && b == drVal)
        return temp->minim;
    else
    {
        int mijl = stVal + (drVal - stVal) / 2;

        ///de stanga
        if(a >= stVal && b <= mijl)
            return findMin(a, b, temp->st);
        else
        ///de dreapta
        if(a >= mijl + 1 && b <= drVal)
            return findMin(a, b, temp->dr);
        else
            ///din ambele parti
            return min(findMin(a, mijl, temp->st), findMin(mijl + 1, b, temp->dr));
    }
}

void tree::getInput(int n, istream &in)
{
    numbers.resize(n);
    for(int i = 0; i < n; i++)
        in>>numbers[i];
}

void tree::makeQueries(int n, istream &in, ostream &out)
{
    bool firstOp = false;
    int a, b, x, type;

    for(int i = 0; i < n; i++)
    {
        in>>a>>b;
        out<<findMin(a - 1, b - 1, head)<<"\n";
    }
}

int main()
{
    tree *T = new tree();
    int n, t; fin >> n >> t;

    T->getInput(n, fin);
    T->buildTree();
    //T->printTree();
    T->makeQueries(t, fin, fout);
}