Cod sursa(job #1672689)

Utilizator BrandonChris Luntraru Brandon Data 2 aprilie 2016 23:25:42
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.13 kb
#include <fstream>
#include <cmath>

using namespace std;

const int INF = 0x3f3f3f3f, MaxN = (1 << 17) + 5;

ifstream cin("arbint.in");
ofstream cout("arbint.out");

int SgTree[2 * MaxN], v[MaxN];
int n, q, abs_right;

inline int LfSon(int node) {
  return 2 * node;
}

inline int RgSon(int node) {
  return 2 * node + 1;
}

inline void BuildTree(int l = 1, int r = abs_right, int node = 1) {
  if(l == r) {
    SgTree[node] = v[l];
    return;
  }

  int med = (l + r) / 2;

  BuildTree(l, med, LfSon(node));
  BuildTree(med + 1, r, RgSon(node));

  SgTree[node] = max(SgTree[LfSon(node)], SgTree[RgSon(node)]);
}

void Update(int pos, int val, int l = 1, int r = abs_right, int node = 1) {
  if(l == r) {
    SgTree[node] = val;
    return;
  }

  int med = (l + r) / 2;

  if(pos <= med) {
    Update(pos, val, l, med, LfSon(node));
  }
  else {
    Update(pos, val, med + 1, r, RgSon(node));
  }

  SgTree[node] = max(SgTree[LfSon(node)], SgTree[RgSon(node)]);
}

int Query(int srch_l, int srch_r, int l = 1, int r = abs_right, int node = 1) {
  if(srch_l <= l and srch_r >= r) {
    return SgTree[node];
  }

  int med = (l + r) / 2;
  int ans = 0;

  if(srch_l <= med) {
    int nxt_qry = Query(srch_l, srch_r, l, med, LfSon(node));
    ans = max(ans, nxt_qry);
  }

  if(srch_r > med) {
    int nxt_qry = Query(srch_l, srch_r, med + 1, r, RgSon(node));
    ans = max(ans, nxt_qry);
  }

  return ans;
}

int main() {
  cin >> n >> q;

  for(int i = 1; i <= n; ++i) {
    cin >> v[i];
  }

  int log2n = log2(n);
  log2n += ((1 << log2n) < n);
  abs_right = (1 << log2n);

  BuildTree();

  for(int i = 1; i <= q; ++i) {
    int a, b;
    bool type;
    cin >> type >> a >> b;

    if(type == 1) {
      Update(a, b);
    }
    else {
      cout << Query(a, b) << '\n';
    }
  }
  return 0;
}

/*#include <fstream>
#include <cmath>

#define NMAX 100005
#define SQROOTMAX 320
#define INF 0x3f3f3f3f
using namespace std;

ifstream cin("arbint.in");
ofstream cout("arbint.out");

class SegmentPosition {
public:
    int left, right;
};

SegmentPosition segm_pos[SQROOTMAX];
int n, q, sqroot, v[NMAX], segm[SQROOTMAX];

inline void update(int pos, int val) {
    int pos_l, pos_r, curr_intv;

    if(pos % sqroot != 0) {
        pos_l = pos / sqroot * sqroot + 1;
        pos_r = pos_l + sqroot - 1;
        curr_intv = pos / sqroot + 1;
    }
    else {
        pos_l = (pos / sqroot - 1) * sqroot + 1;
        pos_r = pos_l + sqroot - 1;
        curr_intv = pos / sqroot;
    }

    v[pos] = val;
    segm[curr_intv] = 0;

    for(int i = pos_l; i <= pos_r; ++i) {
        segm[curr_intv] = max(segm[curr_intv], v[i]);
    }
}

inline int query(int l_qr, int r_qr) {
    int ans = 0, l = INF, r = -1;

    for(int i = 1; i <= sqroot + (n % sqroot != 0); ++i) {
        if(l_qr <= segm_pos[i].left and r_qr >= segm_pos[i].right) {
            if(l > segm_pos[i].left) {
                l = segm_pos[i].left;
            }
            if(r < segm_pos[i].right) {
                r = segm_pos[i].right;
            }
            ans = max(ans, segm[i]);
        }
    }

    if(l == INF and r == -1) {
        l = r_qr;
        r = r_qr + 1;
    }

    for(int i = l_qr; i <= l; ++i) {
        ans = max(ans, v[i]);
    }

    for(int i = r; i <= r_qr; ++i) {
        ans = max(ans, v[i]);
    }

    return ans;
}

int main() {
    cin >> n >> q;

    for(int i = 1; i <= n; ++i) {
        cin >> v[i];
    }

    sqroot = sqrt(n);

    for(int i = 1; i <= sqroot + 1; ++i) {
        segm_pos[i].left = (i - 1) * sqroot + 1;
        segm_pos[i].right = i * sqroot;

        for(int j = segm_pos[i].left; j <= segm_pos[i].right; ++j) {
            segm[i] = max(segm[i], v[j]);
        }
    }

    if(n % sqroot == 0) {
        segm[sqroot + 1] = -1;
    }

    for(int i = 1; i <= q; ++i) {
        int a, b;
        bool type;
        cin >> type >> a >> b;

        if(type == 1) {
            update(a, b);
        }
        else {
            cout << query(a, b) << '\n';
        }
    }
    return 0;
}
*/