Cod sursa(job #1927312)

Utilizator PhilipDumitruPhilip Dumitru PhilipDumitru Data 15 martie 2017 00:44:03
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.64 kb
#include <fstream>
 
using namespace std;
 
namespace PhD {
 
    class SegmentTreeElement
    {
    private:
        //long long value;
    public:
        virtual void change(void *other)
        {
            //value = other.value;
        }
        virtual void combine(void * a, void * b)
        {
            //value = (a.value > b.value) ? a.value : b.value;
        }
		//virtual long long get(value);
    };
 
    template <class T>
    class SegmentTree
    {
    private:
        T* arbore;
        long long arboreSize;
        long long coordonateFixer;
 
        void update(long long node, long long left, long long right, long long *a, long long *b, T* val)
        {
            if (*a <= left && *b >= right) // [a, b] includes [left, right]
            {
                arbore[node].change(val);
				return;
            }
 
            long long mid = (left + right) / 2;
            if (*a <= mid)
            {
                update(2*node, left, mid, a, b, val);
            }

            if (*b > mid)
            {
                update(2*node + 1, mid + 1, right, a, b, val);
            }

            arbore[node].combine(&arbore[2*node], &arbore[2*node+1]);
        }
        T query(long long node, long long left, long long right, long long *a, long long *b)
        {
            if (*a <= left && *b >= right)
            {
                return arbore[node];
            }
 
            long long mid = (left + right) / 2;
            if (*a <= mid)
            {
				T q1 = query(2*node, left, mid, a, b);
                if (*b > mid)
                {
					T q2 = query(2*node + 1, mid + 1, right, a, b);
                    T temp;
                    temp.combine(&q2, &q1);
                    return temp;
                }
                return q1;
            }
            else if (*b > mid)
            {
                return query(2*node + 1, mid + 1, right, a, b);
            }
        }
 
    public:
		// change value in [a, b]
        void changeValue(long long a, long long b, T & value)
        {
			a -= coordonateFixer;
			b -= coordonateFixer;
            update(1, 1, arboreSize, &a, &b, &value);
        }

		// get value in [a, b]
        T getValue(long long int a, long long int b)
        {
			a -= coordonateFixer;
			b -= coordonateFixer;
            return query(1, 1, arboreSize, &a, &b);
        }

        SegmentTree(long long left, long long right)/*:maxSize(s+1)*/
        {
            coordonateFixer = left - 1;
            long long int s = right - left + 1;
            arboreSize = s;
			for (s = 1; s < arboreSize; s <<= 1);
            arbore = new T[s*2];
        }

        ~SegmentTree()
        {
            delete[] arbore;
        }
 
    };
 
}

class STMaxLL : public PhD::SegmentTreeElement
{
    public:
        long long value;
        virtual void change(void * other)
        {
            value = ((STMaxLL*) other)->value;
        }
        virtual void combine(void * a, void * b)
        {
			STMaxLL * x = (STMaxLL*) a;
			STMaxLL * y = (STMaxLL*) b;
            value = (x->value > y->value) ? x->value : y->value;
        }

};

int main()
{
    FILE * fin = fopen("arbint.in", "r");
    FILE * fout = fopen("arbint.out", "w");
 
    int n, m;
	fscanf(fin, "%d%d", &n, &m);

	PhD::SegmentTree<STMaxLL> arbore(1, n);
	STMaxLL tmp;
	for (int i = 1; i <= n; ++i)
	{
		fscanf(fin, "%lld", &(tmp.value));
		arbore.changeValue(i, i, tmp);
	}
	
	long long int x, y, z;
	while (m--)
	{
		fscanf(fin, "%lld%lld%lld", &x, &y, &z);
		if (x)
		{
			tmp.value = z;
			arbore.changeValue(y, y, tmp);
		} else {
			fprintf(fout, "%lld\n", arbore.getValue(y, z).value);
		}
	}

 
    fclose(fin);
    fclose(fout);
    return 0;
}