Cod sursa(job #1193674)

Utilizator ariel_roAriel Chelsau ariel_ro Data 1 iunie 2014 14:13:11
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
#define NX 100010
#define SQRTNX 320
int a[NX], b[SQRTNX], rightPos[SQRTNX], leftPos[SQRTNX];
 
inline int maxim(int left, int right) 
{
    int max = -1;
    for (int i = left; i <= right; i++) 
    {
        if (max < a[i])
            max = a[i];
    }
 
    return max;
}
 
inline int MaximTwoElems(int a, int b) {
       if (a > b) 
		   return a;
       return b;
}

int sqrtMax(int left, int right, int sqrtN, int N)
{
    if (right - left <= sqrtN)
	{
		return maxim(left, right);
	}

	int leftIntA = 1, rightIntA = sqrtN, max = -1, startLeft = N + 2, endRight = 1;
	// interior
	for (int i = 1; i <= sqrtN; i++)
	{	
		if (left <= leftIntA && rightIntA <= right)
		{
			if (leftIntA < startLeft)
			{
				startLeft = leftIntA;
			}

			if (rightIntA > endRight) 
			{
				endRight = rightIntA;
			}

			max = MaximTwoElems(max, b[i]);
		}

		if (rightIntA > right)
		{
			break;
		}

		leftIntA = i * sqrtN + 1;
		rightIntA = leftIntA + sqrtN - 1;
	}

	if (startLeft == N + 2 && endRight == 1)
	{
		startLeft = right;
		endRight = right;
	}

	// left margin
	max = MaximTwoElems(max, maxim(left, startLeft));

	// right margin
	max = MaximTwoElems(max, maxim(endRight, right));

	return max;
}

void updateSqrt(int an, int bn, int sqrtN)
{
	int leftIntA = 1, rightIntA = sqrtN;
	for (int i = 1; i <= sqrtN; i++)
	{
		if (an >= leftIntA && an <= rightIntA)
		{
			b[i] = maxim (leftIntA, rightIntA);
			break;
		}

		leftIntA = i * sqrtN + 1;
		rightIntA = leftIntA + sqrtN - 1;
	}
}
 
int main() 
{
    int N, M, op, an, bn, j = 1;
    freopen("arbint.in", "r", stdin);
    freopen("arbint.out", "w", stdout);
 
    scanf("%d %d", &N, &M);
 
    int sqrtN = sqrt((double)N);
 
    for (int i = 1; i <= N; i++) 
    {
        scanf("%d", &a[i]);
    }
     
	int leftLimit = 1, rightLimit;
    for (int i = 1; i <= sqrtN; i++)
	{
		rightLimit = i * sqrtN;

		b[i] = maxim(leftLimit, rightLimit);

		leftLimit = rightLimit + 1;
	}
 
    for (int i = 1; i <= M; i++)
    {
        scanf("%d %d %d\n", &op, &an, &bn);
 
        switch (op)
        {
        case 0:
            printf("%d\n", sqrtMax(an, bn, sqrtN, N));
            break;
        case 1:
            a[an] = bn;
			updateSqrt(an, bn, sqrtN);
			
            break;
        }
    }
}