Pagini recente » Cod sursa (job #3290441) | Cod sursa (job #1788340) | Cod sursa (job #1958219) | Cod sursa (job #272106) | Cod sursa (job #657697)
Cod sursa(job #657697)
#include <fstream>
#include <iostream>
#include <limits>
#define MAX_SIZE 100001
#define GET_0_BASED_INDEX_PARENT(index) (((index)-1-!((index)%2)) / 2)
using namespace std;
int intervalSize;
int intervalTree[4*MAX_SIZE+1];
void Update(const int index, const int val)
{
int left = 0, right = intervalSize-1;
int intervalTreeIndex = 0;
while (left < right)
{
const int mid = left + (right-left)/2;
if (index <= mid)
{
//cout << index << " <= " << mid << endl;
intervalTreeIndex = 2*intervalTreeIndex + 1;
right = mid;
}
else
{
//cout << index << " > " << mid << endl;
intervalTreeIndex = 2*(intervalTreeIndex+1);
left = mid+1;
}
}
if (left == index)
{
intervalTree[intervalTreeIndex] = val;
//cout << "yes\n";
int parent = GET_0_BASED_INDEX_PARENT(intervalTreeIndex);
while(parent >= 0)
{
intervalTree[parent] = max(intervalTree[2*parent+1], intervalTree[2*(parent+1)]);
intervalTreeIndex = parent;
parent = GET_0_BASED_INDEX_PARENT(intervalTreeIndex);
}
}
}
int QueryElementaryInterval(const int index)
{
int left = 0, right = intervalSize-1;
int intervalTreeIndex = 0;
while (left < right)
{
const int mid = left + (right-left)/2;
if (index <= mid)
{
//cout << index << " <= " << mid << endl;
intervalTreeIndex = 2*intervalTreeIndex + 1;
right = mid;
}
else
{
//cout << index << " > " << mid << endl;
intervalTreeIndex = 2*(intervalTreeIndex+1);
left = mid+1;
}
}
if (left == index)
{
return intervalTree[intervalTreeIndex];
}
return -1;
}
int QueryLeftSubInterval(int left, int right, const int finalLeft, int intervalTreeIndex)
{
int maximum = numeric_limits<int>::min();
while (1)
{
const int mid = left + (right-left)/2;
if (finalLeft == left)
{
//intervalTreeIndex = 2*(intervalTreeIndex+1);
maximum = max(maximum, intervalTree[intervalTreeIndex]);
break;
}
else if (finalLeft <= mid)
{
maximum = max(maximum, intervalTree[2*(intervalTreeIndex+1)]);
intervalTreeIndex = 2*intervalTreeIndex+1;
right = mid;
}
else
{
left = mid+1;
intervalTreeIndex = 2*(intervalTreeIndex+1);
}
}
return maximum;
}
int QueryRightSubInterval(int left, int right, const int finalRight, int intervalTreeIndex)
{
int maximum = numeric_limits<int>::min();
while (1)
{
const int mid = left + (right-left)/2;
if (finalRight == right)
{
//intervalTreeIndex = 2*intervalTreeIndex+1;
maximum = max(maximum, intervalTree[intervalTreeIndex]);
break;
}
else if (finalRight > mid)
{
maximum = max(maximum, intervalTree[2*intervalTreeIndex+1]);
intervalTreeIndex = 2*(intervalTreeIndex+1);
left = mid+1;
}
else
{
right = mid;
intervalTreeIndex = 2*intervalTreeIndex+1;
}
}
return maximum;
}
int Query(const int l, const int r)
{
int maximum = 0;
int intervalTreeIndex = 0;
int left = 0, right = intervalSize-1;
if (l == r)
{
return QueryElementaryInterval(l);
}
int mid = left + (right-left)/2;
while (r <= mid || l > mid)
{
if (r <= mid)
{
right = mid;
intervalTreeIndex = 2*intervalTreeIndex+1;
}
else if (l > mid)
{
left = mid+1;
intervalTreeIndex = 2*(intervalTreeIndex+1);
}
mid = left + (right-left)/2;
//cout << l << " " << r << " included in " << left << " " << right << endl;
}
//cout << "Left = " << left << endl;
//cout << "Right = " << right << endl;
/*cout << QueryLeftSubInterval(left, mid, 2*intervalTreeIndex+1) << endl;
cout << QueryRightSubInterval(mid+1, right, 2*(intervalTreeIndex+1)) << endl;*/
//cout << "Mid = " << mid << endl;
maximum = max(QueryLeftSubInterval(left, mid, l, 2*intervalTreeIndex+1),
QueryRightSubInterval(mid+1, right, r, 2*(intervalTreeIndex+1)));
return maximum;
}
int main()
{
int m;
fstream fin("arbint.in", fstream::in);
fstream fout("arbint.out", fstream::out);
fin >> intervalSize >> m;
//cout << intervalSize << " " << m << endl << endl;
for (int i=0; i<intervalSize; ++i)
{
int x;
fin >> x;
//cout << x << " ";
Update(i,x);
}
//cout << endl;
for (int i=0; i<m; ++i)
{
int opt, a, b;
fin >> opt >> a >> b;
switch (opt)
{
case 0:
{
//cout << opt << " " << a-1 << " " << b-1 << endl;
fout << Query(a-1,b-1) << "\n";
}; break;
case 1:
{
//cout << opt << " " << a-1 << " " << b << endl;
Update(a-1,b);
}; break;
}
}
/*intervalSize = 5;
Update(0,4);
Update(1,3);
Update(2,2);
Update(3,6);
Update(4,1);
for (int i=0; i<4*intervalSize+1; ++i)
{
cout << intervalTree[i] << " ";
}
cout << endl;
cout << Query(1,2) << endl;
cout << Query(4,4) << endl;*/
//fin.close();
//fout.close();
return 0;
}