Pagini recente » Cod sursa (job #2253481) | Cod sursa (job #2427193) | Cod sursa (job #2917187) | Cod sursa (job #2130395) | Cod sursa (job #842577)
Cod sursa(job #842577)
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <vector>
#define MAX_SIZE 100001
using namespace std;
typedef unsigned int uint32;
template<class T, class Compare = less<T> >
class CIntervalTree
{
public:
CIntervalTree(const int size, const T& defaultValue) :
intervalSize(size)
{
vValues.resize(size + 1);
vValues[size] = defaultValue;
intervalTree = (int*)calloc((4*size+2), sizeof(int));
}
~CIntervalTree()
{
vValues.clear();
free(intervalTree);
}
inline void Update(const int index, const T& value)
{
vValues[index] = value;
UpdateIndex(index);
}
inline void Update(const int index)
{
UpdateIndex(index);
}
inline void UpdateIndex(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)
{
intervalTreeIndex = GetLeftSubtree(intervalTreeIndex);
right = mid;
}
else
{
intervalTreeIndex = GetRightSubtree(intervalTreeIndex);
left = mid+1;
}
}
if (left == index)
{
intervalTree[intervalTreeIndex] = index;
int parent = GetZeroBasedIndexOfParent(intervalTreeIndex);
while(parent >= 0)
{
if (compare(vValues[intervalTree[GetLeftSubtree(parent)]], vValues[intervalTree[GetRightSubtree(parent)]]))
{
intervalTree[parent] = intervalTree[GetLeftSubtree(parent)];
}
else
{
intervalTree[parent] = intervalTree[GetRightSubtree(parent)];
}
intervalTreeIndex = parent;
parent = GetZeroBasedIndexOfParent(intervalTreeIndex);
}
}
}
inline int QueryIndex(const int l, const int r) const
{
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 = GetLeftSubtree(intervalTreeIndex);
}
else if (l > mid)
{
left = mid+1;
intervalTreeIndex = GetRightSubtree(intervalTreeIndex);
}
mid = left + (right-left)/2;
}
const int leftIndex = QueryLeftSubInterval(left, mid, l, GetLeftSubtree(intervalTreeIndex));
const int rightIndex = QueryRightSubInterval(mid+1, right, r, GetRightSubtree(intervalTreeIndex));
if (compare(vValues[leftIndex], vValues[rightIndex]))
{
return leftIndex;
}
return rightIndex;
}
inline T& QueryValue(const int l, const int r)
{
return vValues[QueryIndex(l,r)];
}
inline const T& QueryValue(const int l, const int r) const
{
return vValues[QueryIndex(l,r)];
}
inline T& GetValueAt(const int index)
{
return vValues[index];
}
inline const T& GetValueAt(const int index) const
{
return vValues[index];
}
private:
inline int GetZeroBasedIndexOfParent(int index) const
{
return (index-1-!(index%2)) / 2;
}
inline int GetLeftSubtree(int index) const
{
return (index<<1)+1;
}
inline int GetRightSubtree(int index) const
{
return (index+1)<<1;
}
inline int QueryElementaryInterval(const int index) const
{
int left = 0, right = intervalSize-1;
int intervalTreeIndex = 0;
while (left < right)
{
const int mid = left + (right-left)/2;
if (index <= mid)
{
intervalTreeIndex = GetLeftSubtree(intervalTreeIndex);
right = mid;
}
else
{
intervalTreeIndex = GetRightSubtree(intervalTreeIndex);
left = mid+1;
}
}
if (left == index)
{
return intervalTree[intervalTreeIndex];
}
return intervalTree[intervalSize];
}
inline int QueryLeftSubInterval(int left, int right, const int finalLeft, int intervalTreeIndex) const
{
int foundIndex = intervalSize;
while (finalLeft != left)
{
const int mid = left + (right-left)/2;
if (finalLeft <= mid)
{
if (compare(vValues[intervalTree[GetRightSubtree(intervalTreeIndex)]], vValues[foundIndex]))
{
foundIndex = intervalTree[GetRightSubtree(intervalTreeIndex)];
}
intervalTreeIndex = GetLeftSubtree(intervalTreeIndex);
right = mid;
}
else
{
left = mid+1;
intervalTreeIndex = GetRightSubtree(intervalTreeIndex);
}
}
if (compare(vValues[intervalTree[intervalTreeIndex]], vValues[foundIndex]))
{
foundIndex = intervalTree[intervalTreeIndex];
}
return foundIndex;
}
inline int QueryRightSubInterval(int left, int right, const int finalRight, int intervalTreeIndex) const
{
int foundIndex = intervalSize;
while (finalRight != right)
{
const int mid = left + (right-left)/2;
if (finalRight > mid)
{
if (compare(vValues[intervalTree[GetLeftSubtree(intervalTreeIndex)]], vValues[foundIndex]))
{
foundIndex = intervalTree[GetLeftSubtree(intervalTreeIndex)];
}
intervalTreeIndex = GetRightSubtree(intervalTreeIndex);
left = mid+1;
}
else
{
right = mid;
intervalTreeIndex = GetLeftSubtree(intervalTreeIndex);
}
}
if (compare(vValues[intervalTree[intervalTreeIndex]], vValues[foundIndex]))
{
foundIndex = intervalTree[intervalTreeIndex];
}
return foundIndex;
}
Compare compare;
const int intervalSize;
int *intervalTree;
vector<T> vValues;
};
int main()
{
int m, intervalSize;
fstream fin("arbint.in", fstream::in);
fstream fout("arbint.out", fstream::out);
fin >> intervalSize >> m;
CIntervalTree<int, greater<int> > intervalTree(intervalSize, 0);
for (int i=0; i<intervalSize; ++i)
{
int x;
fin >> x;
intervalTree.Update(i,x);
}
for (int i=0; i<m; ++i)
{
int opt, a, b;
fin >> opt >> a >> b;
switch (opt)
{
case 0:
{
fout << intervalTree.QueryValue(a-1,b-1) << "\n";
}; break;
case 1:
{
intervalTree.Update(a-1,b);
}; break;
}
}
fin.close();
fout.close();
return 0;
}