Mai intai trebuie sa te autentifici.
Cod sursa(job #1119166)
Utilizator | Data | 24 februarie 2014 15:50:07 | |
---|---|---|---|
Problema | Arbori de intervale | Scor | 50 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 2.9 kb |
// Include
#include <cstdio>
#include <algorithm>
using namespace std;
// Definitii
#define leftSon node*2
#define rightSon node*2+1
// Constante
const int sz = (int)1e5+1;
// Functii
// Modifica elementul de pe pozitia pos a vectorului in valoarea val.
// In arbore, elementul va reprezenta intervalul [pos, pos] si se va gasi pe pozitia node
void update(int node, int left, int right, int pos, int val);
// Returneaza valoarea maxima de pe intervalul leftRange, rightRange.
// Variabilele node, left si right simbolizeaza acelasi lucru ca in functia update
int query(int node, int left, int right, int leftRange, int rightRange);
// Variabile
int num;
int questions, type;
int tree[4*sz];
char inputStr[31];
// Main
int main()
{
freopen("arbint.in", "rt", stdin);
freopen("arbint.out", "wt", stdout);
scanf("%d%d", &num, &questions);
int val;
for(int i=1 ; i<=num ; ++i)
{
scanf("%d", &val);
update(1, 1, num, i, val);
}
while(questions--)
{
scanf("%d", &type);
int pos, val, leftRange, rightRange;
if(type)
{
scanf("%d%d", &pos, &val);
update(1, 1, num, pos, val);
}
else
{
scanf("%d%d", &leftRange, &rightRange);
printf("%d\n", query(1, 1, num, leftRange, rightRange));
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
void update(int node, int left, int right, int pos, int val)
{
// Daca am ajuns la un interval unitar, updatez arborele
if(left == right)
{
tree[node] = val;
return;
}
// In caz contrar, ma uit in ce directie trebuie sa merg, in functie de pozitia pe care trebuie pus elementul
int mid = (left + right) / 2;
if(pos <= mid)
update(leftSon, left, mid, pos, val);
else
update(rightSon, mid+1, right, pos, val);
// Valoarea de pe nodul curent va fi maximul de pe intervalul [left, right] ce-l reprezinta, deci maximul fiilor
tree[node] = max(tree[leftSon], tree[rightSon]);
}
int query(int node, int left, int right, int leftRange, int rightRange)
{
// Daca intervalul curent [left, right] e continut in intervalul mare [leftRange, rightRange]
// Returnez valoarea maxima a intervalului
if(leftRange <= left && right <= rightRange)
return tree[node];
// In caz contrar, ma uit in ce directie trebuie sa merg, in functie de pozitia intetrvalului cautat.
// E posibil ca raspunsul sa fie o reuniune de intervale, deci va trebui sa le verific pe ambele
int mid = (left + right) / 2;
int max1=0, max2=0;
// Daca capatul din stanga al intervalului cautat este in stanga mijlocului, trebuie sa caut in intervalul [left, mid]
if(leftRange <= mid)
max1 = query(leftSon, left, mid, leftRange, rightRange);
// Daca capatul din dreapta al intervalului cautat este in dreapta mijlocului, trebuie sa caut in intervalul (mid, right]
if(mid < rightRange)
max2 = query(rightSon, mid+1, right, leftRange, rightRange);
return max(max1, max2);
}