HDU 1754 I Hate It (线段树(指针))

Problem

Problem Description

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。

这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

Input

本题目包含多组测试,请处理到文件结束。

在每个测试的第一行,有两个正整数 \(N\)\(M\) ( \(0<N<=200000\),\(0<M<5000\) ),分别代表学生的数目和操作的数目。

学生ID编号分别从\(1\)编到\(N\)

第二行包含\(N\)个整数,代表这\(N\)个学生的初始成绩,其中第\(i\)个数代表ID为\(i\)的学生的成绩。

接下来有\(M\)行。每一行有一个字符 \(C\) (只取'Q''U') ,和两个正整数\(A\)\(B\)

\(C\)'Q'的时候,表示这是一条询问操作,它询问ID从\(A\)\(B\)(包括\(A\),\(B\))的学生当中,成绩最高的是多少。

\(C\)'U'的时候,表示这是一条更新操作,要求把ID为\(A\)的学生的成绩更改为\(B\)

Output

对于每一次询问操作,在一行里面输出最高成绩。

Sample Input

5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5

Sample Output

5
6
5
9

Solution

线段树区间最值板子题, 这些不解释, 这题主要用来测试析构函数。

由于我只会经常写指针版的线段树, 多组数据的题目经常MLE, 所以要写一个函数来释放内存。为了方便就用析构函数(在当前变量内存空间释放时调用), 就不用写个递归函数了。

Code

#include <algorithm>
#include <cstdio>
class SegmentTree {
 private:
  struct Node {
    int value;
    Node *left, *right;
    int L, R;
    inline void Update() {
      if (this->left) {
        this->value = std::max(this->left->value, this->right->value);
      }
    }
    Node(const int &l, const int &r) {
      this->L = l, this->R = r;
      this->left = this->right = NULL;
      if (l == r) {
        scanf("%d", &this->value);
      } else {
        register int mid((l + r) >> 1);
        this->left = new Node(l, mid);
        this->right = new Node(mid + 1, r);
        this->Update();
      }
    }
    ~Node() { //The destructor
      if (this->left) {
        delete this->left;
        delete this->right;
      }
    }
    inline int Query(const int &l, const int &r) {
      if (this->L >= l && this->R <= r) {
        return this->value;
      } else {
        register int mid((this->L + this->R) >> 1), ret(-2147483648);
        if (l <= mid) ret = std::max(ret, this->left->Query(l, r));
        if (mid < r) ret = std::max(ret, this->right->Query(l, r));
        return ret;
      }
    }
    inline void Modify(const int &kIndex, const int &kDelta) {
      if (this->L == this->R) {
        this->value = kDelta;
      } else {
        register int mid((this->L + this->R) >> 1);
        if (kIndex <= mid)
          this->left->Modify(kIndex, kDelta);
        else
          this->right->Modify(kIndex, kDelta);
        this->Update();
      }
    }
  } * root;

 public:
  SegmentTree() { this->root = NULL; }
  inline void Clear() {
    if (this->root) {
      delete this->root;
      this->root = NULL;
    }
  }
  inline void Build(const int &l, const int &r) { this->root = new Node(l, r); }
  inline int Query(const int &l, const int &r) {
    return this->root->Query(l, r);
  }
  inline void Modify(const int &kIndex, const int &kDelta) {
    this->root->Modify(kIndex, kDelta);
  }
} T;
int n, m;
char C;
int A, B;
int main(int argc, char const *argv[]) {
  while (~scanf("%d %d", &n, &m)) {
    T.Clear();
    T.Build(1, n);
    while (m--) {
      scanf("\n%c %d %d", &C, &A, &B);
      switch (C) {
        case 'Q': {
          printf("%d\n", T.Query(A, B));
          break;
        }
        case 'U': {
          T.Modify(A, B);
          break;
        }
      }
    }
  }
  return 0;
}

posted @ 2018-10-25 19:53  Acenaphthene  阅读(154)  评论(0编辑  收藏  举报