Pagini recente » Cod sursa (job #354345) | Cod sursa (job #1285589) | Cod sursa (job #2022781) | Cod sursa (job #2893984) | Cod sursa (job #2099181)
#include<algorithm>
#include<iostream>
#include<fstream>
using namespace std;
ifstream in("datorii.in");
ofstream out("datorii.out");
struct interval
{
int leftBoundary, rightBoundary;
int value; /// The values of its son and itself :)
interval *leftSon, *rightSon;
};
const int N = 15001;
void createSons(interval *x)
{
x->value = 0;
////cout<<"Father\n";
//cout<<"("<<x->leftBoundary<<", "<<x->rightBoundary<<")\n";
if(x->leftBoundary == x->rightBoundary)
{
x->leftSon = NULL;
x->rightSon = NULL;
}
else if(x->leftBoundary < x->rightBoundary)
{
interval *leftSon = new interval;
interval *rightSon = new interval;
int middleBoundary = (x->leftBoundary + x->rightBoundary) / 2;
leftSon->leftBoundary = x->leftBoundary;
leftSon->rightBoundary = middleBoundary;
rightSon->leftBoundary = middleBoundary + 1;
rightSon->rightBoundary = x->rightBoundary;
x->leftSon = leftSon;
x->rightSon = rightSon;
//cout<<"Left son\n";
createSons(leftSon);
//cout<<"Right son\n";
createSons(rightSon);
//cout<<"End__\n";
}
else
{
cerr<<"Error! Left boundary > Right boundary\n";
}
}
void createIntervalTree(interval *&root, int leftBoundary, int rightBoundary)
{
root = new interval;
root->leftBoundary = leftBoundary;
root->rightBoundary = rightBoundary;
createSons(root);
}
int query(interval *x, int query_leftBoundary, int query_rightBoundary)
{
if(!x) /// NULL node reached. Is it even possible?
{
//cerr<<"Error! Queried node is NULL!\n";
return 0; /// Identity element
}
if(x->rightBoundary < query_leftBoundary || x->leftBoundary > query_rightBoundary) /// Interval is outside query
{
return 0; /// Identity element
}
else if(x->leftBoundary >= query_leftBoundary && x->rightBoundary <= query_rightBoundary) /// Interval is inside query boundaries
{
return x->value;
}
else /// Interval partially matches the query boundaries -> query its children!
{
int leftSonQuery = query(x->leftSon, query_leftBoundary, query_rightBoundary);
int rightSonQuery = query(x->rightSon, query_leftBoundary, query_rightBoundary);
return leftSonQuery + rightSonQuery;
}
}
void updateIndex(interval *x, int index, int value)
{
if(!x) /// NULL node reached
return;
if(index < x->leftBoundary || index > x->rightBoundary) /// Index is outside interval
{
return;
}
else
{
x->value += value;
updateIndex(x->leftSon, index, value);
updateIndex(x->rightSon, index, value);
}
}
int main()
{
/// Variables
interval *rootInterval;
int n,m;
/// Input
in>>n>>m;
createIntervalTree(rootInterval, 1, n);
for(int i=0; i<n; ++i){
int x;
in>>x;
updateIndex(rootInterval, i+1, x);
}
for(int i=0; i<m; ++i)
{
int a,b,caz;
in>>caz>>a>>b;
if(caz == 0)
updateIndex(rootInterval, a, -b);
else
out<<query(rootInterval, a, b)<<"\n";
}
return 0;
}