Ciao a tutti, ho iniziato da poco strutture dati e cercando un po’ sono arrivato a quest’implementazione. Mi risolve velocemente solo i task 1 e 2. Non trovo dove sia l’errore, eppure mi sembra che il programma sia N*logN. Qualcuno riesce a darmi qualche consiglio per capire dove sbaglio? Grazie
#include <utility>
#include <vector>
using namespace std;
// variabili globali
vector <int> T;
vector <int> t;
int sizeN;
// "-right" trova l'indice del primo elemento più grande di x a destra
int get_right(int v, int tl, int tr, int l, int r, int x) {
if(tl > r || tr < l) return -1;
if(t[v] <= x) return -1;
if (tl== tr) return tl;
int tm = tl + (tr-tl)/2;
int left = get_right(2*v, tl, tm, l, r, x);
if(left != -1) return left;
return get_right(2*v+1, tm+1, tr, l ,r, x);
}
// "-left" trova l'indice del primo elemento più grande di x a sinistra
int get_left(int v, int tl, int tr, int l, int r, int x) {
if(tl > r || tr < l) return -1;
if(t[v] <= x) return -1;
if (tl== tr) return tl;
int tm = tl + (tr-tl)/2;
int right = get_left(2*v+1, tm+1, tr, l ,r, x);
if(right != -1) return right;
return get_left(2*v, tl, tm, l, r, x);
}
//"chiedi" chiama le funzioni "-left" e "-right" e stampa l'output
pair<int, int> chiedi(int x) {
int right = get_right(1, 0, sizeN-1, x, sizeN-1, T[x]);
if (right == -1) right = sizeN-1;//se l'elemento non esiste, prendi tutto
int left = get_left(1, 0, sizeN-1, 0, x, T[x]);
if (left == -1) left = 0;
return {left, right};
}
//"update" aggiorna il segment tree in base alla query
void update(int v, int tl, int tr, int pos, int new_val) {
if (tl == tr) {
t[v] = new_val;
} else {
int tm = (tl + tr) / 2;
if (pos <= tm)
update(v*2, tl, tm, pos, new_val);
else
update(v*2+1, tm+1, tr, pos, new_val);
t[v] = max(t[v*2], t[v*2+1]);
}
}
//"cambia" chiama la funzione "update"
void cambia(int x, int h) {
T[x] = h;//aggiorna il vettore base
update(1, 0, sizeN-1, x, h);//aggiorna il segment tree
return;
}
//"build" costruisce il segment tree
void build(vector <int> a, int v, int tl, int tr) {
if (tl == tr) {
t[v] = a[tl];
} else {
int tm = (tl + tr) / 2;
build(a, v*2, tl, tm);
build(a, v*2+1, tm+1, tr);
t[v] = max(t[v*2], t[v*2+1]);
}
}
//"inizializza" prima funzione chiamata: chiama la funzione "build"
void inizializza(int N, vector<int> H) {
sizeN = N;
t.resize(4*N);
T = H;
build(T, 1, 0, N-1);
return;
}