Cod sursa(job #3134068)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 28 mai 2023 10:03:37
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include<fstream>
#include<random>
#include<ctime>
using namespace std;

ifstream cin("rmq.in");
ofstream cout("rmq.out");

mt19937 rng(time(nullptr));

struct nod
{
    int val,best,p,sz;
    nod *c[2];
    nod(int &a) : val(a),best(a),p(rng()),sz(1) {c[0] = c[1] = NULL;}
};

int size(nod *&treap){return treap ? treap->sz : 0;}
int ga(nod *&treap){return treap ? treap->best : (1 << 30);}

void split(nod *r,nod *&left,nod *&right,int x,int cheie = 0)
{
    if(!r) left = right = NULL;
    else
        {
            cheie += size(r->c[0]); r->best = r->val;
            if(cheie <= x) split(r->c[1],r->c[1],right,x,cheie + 1),left = r;
            else split(r->c[0],left,r->c[0],x,cheie - size(r->c[0])),right = r;
            r->sz = 1 + size(r->c[0]) + size(r->c[1]);
            r->best = min(r->val,min(ga(r->c[0]),ga(r->c[1])));
        }
}

void merge(nod *&r,nod *left,nod *right)
{
    if(!left || !right) r = left ? left : right;
    else
        {
            r->best = r->val;
            if(left->p > right->p) merge(left->c[1],left->c[1],right),r = left;
            else merge(right->c[0],left,right->c[0]),r = right;
            r->sz = 1 + size(r->c[0]) + size(r->c[1]);
            r->best = min(r->val,min(ga(r->c[0]),ga(r->c[1])));
        }
}

int main()
{
    int n,a,b,q,c; nod *treap = nullptr;
    cin >> n >> q; for(int i = 1; i <= n ; i++)
    {
        cin >> a;
        merge(treap,treap,new nod(a));
    }

    while(q--)
    {
        c = 1;
        if(c == 1)
            {
                nod *unu,*doi,*trei,*patru;
                cin >> a >> b; a--,b--;
                split(treap,unu,doi,a - 1);
                split(doi,trei,patru,b - a);
                cout << trei->best << '\n';
                merge(doi,trei,patru);
                merge(treap,unu,doi);
            }
        else
            {
                nod *unu,*doi,*trei;
                cin >> a >> b; a--;
                split(treap,unu,doi,a - 1);
                split(doi,doi,trei,0,0);
                merge(trei,new nod(b),trei);
                merge(treap,unu,trei);
            }

    }
}