Cod sursa(job #1190902)

Utilizator ariel_roAriel Chelsau ariel_ro Data 25 mai 2014 21:41:13
Problema Arbori de intervale Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.43 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 = a[left];
    for (int i = left + 1; 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 (abs(right - left) <= sqrtN) 
    {
        return maxim(left, right);
    }
 
    int max = -1;
    // interior
    for (int i = 1; i <= sqrtN; i++) 
    {
        if (left <= leftPos[i] && right >= rightPos[i])
        {
            max = MaximTwoElems(max, b[i]);
        } else if (right < rightPos[i]) {
            break;
        }
    }
 
    int bLeftRem = left % sqrtN;
    int bRightRem = right % sqrtN; 
 
    // left remainder
    if (bLeftRem != 1) 
    {
        max = MaximTwoElems(max, maxim(left, (sqrtN - bLeftRem) + left));
    }
 
    // right remainder
    if (bRightRem != 0) 
    {
        max = MaximTwoElems(max, maxim(right - bRightRem + 1, right));
    }
 
    return max;
}
 
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 = 1;
    while (sqrtN * sqrtN < N) 
    {
        sqrtN++;
    }
    sqrtN--;
    int left = 1;
 
    for (int i = 1; i <= N; i++) 
    {
        scanf("%d", &a[i]);
    }
     
    for (int i = 1; i  <= sqrtN; i++)
    {
        leftPos[i] = i * sqrtN - sqrtN + 1;
        rightPos[i] = i * sqrtN;
        b[i] = maxim(leftPos[i], rightPos[i]);
    }
 
    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;
            int bi = 1, left = 1, right = N;
            for (int i = 1; i <= sqrtN; i++)
            {
                if (an >= leftPos[i] && an <= rightPos[i]) 
                {
                    bi = i;
                    left = leftPos[i];
                    right = rightPos[i];
                }
            }
            b[bi] = maxim(left, right);
            break;
        }
    }
}