Problem p02610 (C++) — buggy submission, verdict: Time Limit Exceeded


#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <vector>

// #define T int

class T {
public:
  int index;
  bool vacant;
  T() : index(-1), vacant(false) {}
  T(int index) : index(index), vacant(true) {}
  T(const T &value) : index(value.index), vacant(value.vacant) {}
  T &operator=(const T &value) {
    this->index = value.index;
    this->vacant = value.vacant;
    return *this;
  }
};

const T *merge(const T *L, const T *R) {
  if (R->vacant) {
    return R;
  } else {
    return L;
  }
}

template <size_t W> class SegmentTree;

template <size_t W> class SegmentTreeNode {
private:
  const size_t start;
  const size_t end;
  SegmentTreeNode<(W + 1) / 2> L;
  SegmentTreeNode<W / 2> R;

public:
  SegmentTreeNode(const std::vector<T> &values, size_t start)
      : start(start), end(start + W), L(values, start),
        R(values, start + (W + 1) / 2) {
    value = merge(L.value, R.value);
  }
  const T *value;
  void print() {
    L.print();
    R.print();
  }
  inline void update(size_t index, const T &value) {
    if (start <= index && index < end) {
      L.update(index, value);
      R.update(index, value);
      this->value = merge(L.value, R.value);
    }
  }
  inline void update() {
    L.update();
    R.update();
    this->value = merge(L.value, R.value);
  }
  inline const T *pick(size_t start, size_t end) {
    if (start <= this->start && this->end <= end) {
      return value;
    } else if (this->start<end &&this->end> start) {
      auto l = L.pick(start, end);
      auto r = R.pick(start, end);
      if (l == NULL) {
        return r;
      } else if (r == NULL) {
        return l;
      }
      return merge(l, r);
    } else {
      return NULL;
    }
  }
};

template <> class SegmentTreeNode<1> {
private:
  const size_t index;

public:
  SegmentTreeNode(const std::vector<T> &values, size_t start)
      : index(start), value(&values[start]) {}
  const T *value;
  void print() { std::cout << index << std::endl; }
  inline void update(size_t index, const T &value) {}
  inline void update() {}
  inline const T *pick(size_t start, size_t end) {
    if (start <= this->index && this->index < end) {
      return value;
    } else {
      return NULL;
    }
  }
};

template <size_t W> class SegmentTree {
private:
  std::vector<T> values;
  SegmentTreeNode<W> *root;

public:
  SegmentTree() : values(W) { root = new SegmentTreeNode<W>(values, 0); }
  SegmentTree(const std::vector<T> &values) : values(values) {
    root = new SegmentTreeNode<W>(values, 0);
  }
  SegmentTree(const std::vector<T> &&values) : values(values) {
    root = new SegmentTreeNode<W>(values, 0);
  }
  ~SegmentTree() { delete root; }
  void print() { root->print(); }
  void update(size_t index, const T &&value) {
    values[index] = value;
    root->update(index, values[index]);
  }
  void clear(const T &value) {
    for (auto i = values.begin(); i != values.end(); i++) {
      *i = value;
    }
    root->update();
  }
  const T *pick(size_t start, size_t end) { return root->pick(start, end); }
  const std::vector<T> &get_values() { return values; }
};

const int MAX = 200000;

class Camel {
public:
  long long D, L, R, K;
  Camel(long long D, long long L, long long R, long long K)
      : D(D), L(L), R(R), K(K) {}
  bool operator<(const Camel &value) { return D > value.D; }
};

using namespace std;

// #include "print.cpp"

long long calc(SegmentTree<MAX> &st, vector<Camel> &camels) {
  sort(camels.begin(), camels.end());
  long long count = camels.size();
  //	st.clear(T());

  for (int i = 0; i < count; i++) {
    st.update(i, T(i));
  }
  long long score = 0;
  //	vector<pair<int, int>> train(count, pair<int, int>(-1, -1));
  for (auto &camel : camels) {
    if (camel.K > 0) {
      auto p = st.pick(0, min(camel.K, count));
      //			printe(camel.D, camel.L, camel.R, camel.K,
      //p->index, p->vacant);
      if (p != NULL && p->index >= 0 && p->vacant) {
        //				train[p->index] = pair<int, int>(camel.L,
        //camel.R); 				printe(st.get_values()[0].vacant);
        st.update(p->index, T());
        //				printe(st.get_values()[0].vacant);
        score += camel.L;
      } else {
        score += camel.R;
      }
    } else {
      score += camel.R;
    }
  }
  //	printe(train);
  return score;
}

int main(void) {
  SegmentTree<MAX> st;

  int T;

  cin >> T;
  for (int i = 0; i < T; i++) {
    int N;
    cin >> N;
    vector<Camel> camels_l;
    vector<Camel> camels_r;
    for (int j = 0; j < N; j++) {
      long long K, L, R;
      cin >> K;
      cin >> L;
      cin >> R;

      const long long D = L - R;
      if (D >= 0) {
        camels_l.push_back(Camel(D, L, R, K));
      } else {
        camels_r.push_back(Camel(-D, R, L, N - K));
      }
    }

    cout << calc(st, camels_l) + calc(st, camels_r) << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:


#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <vector>

// #define T int

class T {
public:
  int index;
  bool vacant;
  T() : index(-1), vacant(false) {}
  T(int index) : index(index), vacant(true) {}
  T(const T &value) : index(value.index), vacant(value.vacant) {}
  T &operator=(const T &value) {
    this->index = value.index;
    this->vacant = value.vacant;
    return *this;
  }
};

const T *merge(const T *L, const T *R) {
  if (R->vacant) {
    return R;
  } else {
    return L;
  }
}

template <size_t W> class SegmentTree;

template <size_t W> class SegmentTreeNode {
private:
  const size_t start;
  const size_t end;
  SegmentTreeNode<(W + 1) / 2> L;
  SegmentTreeNode<W / 2> R;

public:
  SegmentTreeNode(const std::vector<T> &values, size_t start)
      : start(start), end(start + W), L(values, start),
        R(values, start + (W + 1) / 2) {
    value = merge(L.value, R.value);
  }
  const T *value;
  void print() {
    L.print();
    R.print();
  }
  inline void update(size_t index, const T &value) {
    if (start <= index && index < end) {
      L.update(index, value);
      R.update(index, value);
      this->value = merge(L.value, R.value);
    }
  }
  inline void update() {
    L.update();
    R.update();
    this->value = merge(L.value, R.value);
  }
  inline const T *pick(size_t start, size_t end) {
    if (start <= this->start && this->end <= end) {
      return value;
    } else if (this->start<end &&this->end> start) {
      auto l = L.pick(start, end);
      auto r = R.pick(start, end);
      if (l == NULL) {
        return r;
      } else if (r == NULL) {
        return l;
      }
      return merge(l, r);
    } else {
      return NULL;
    }
  }
};

template <> class SegmentTreeNode<1> {
private:
  const size_t index;

public:
  SegmentTreeNode(const std::vector<T> &values, size_t start)
      : index(start), value(&values[start]) {}
  const T *value;
  void print() { std::cout << index << std::endl; }
  inline void update(size_t index, const T &value) {}
  inline void update() {}
  inline const T *pick(size_t start, size_t end) {
    if (start <= this->index && this->index < end) {
      return value;
    } else {
      return NULL;
    }
  }
};

template <size_t W> class SegmentTree {
private:
  std::vector<T> values;
  SegmentTreeNode<W> *root;

public:
  SegmentTree() : values(W) { root = new SegmentTreeNode<W>(values, 0); }
  SegmentTree(const std::vector<T> &values) : values(values) {
    root = new SegmentTreeNode<W>(values, 0);
  }
  SegmentTree(const std::vector<T> &&values) : values(values) {
    root = new SegmentTreeNode<W>(values, 0);
  }
  ~SegmentTree() { delete root; }
  void print() { root->print(); }
  void update(size_t index, const T &&value) {
    values[index] = value;
    root->update(index, values[index]);
  }
  void clear(const T &value) {
    for (auto i = values.begin(); i != values.end(); i++) {
      *i = value;
    }
    root->update();
  }
  const T *pick(size_t start, size_t end) { return root->pick(start, end); }
  const std::vector<T> &get_values() { return values; }
};

const int MAX = 200000;

class Camel {
public:
  long long D, L, R, K;
  Camel(long long D, long long L, long long R, long long K)
      : D(D), L(L), R(R), K(K) {}
  bool operator<(const Camel &value) { return D > value.D; }
};

using namespace std;

// #include "print.cpp"

long long calc(SegmentTree<MAX> &st, vector<Camel> &camels) {
  sort(camels.begin(), camels.end());
  long long count = camels.size();
  st.clear(T());

  for (int i = 0; i < count; i++) {
    st.update(i, T(i));
  }
  long long score = 0;
  //	vector<pair<int, int>> train(count, pair<int, int>(-1, -1));
  for (auto &camel : camels) {
    if (camel.K > 0) {
      auto p = st.pick(0, min(camel.K, count));
      //			printe(camel.D, camel.L, camel.R, camel.K,
      //p->index, p->vacant);
      if (p != NULL && p->index >= 0 && p->vacant) {
        //				train[p->index] = pair<int, int>(camel.L,
        //camel.R); 				printe(st.get_values()[0].vacant);
        st.update(p->index, T());
        //				printe(st.get_values()[0].vacant);
        score += camel.L;
      } else {
        score += camel.R;
      }
    } else {
      score += camel.R;
    }
  }
  //	printe(train);
  return score;
}

int main(void) {
  SegmentTree<MAX> st;

  int T;

  cin >> T;
  for (int i = 0; i < T; i++) {
    int N;
    cin >> N;
    vector<Camel> camels_l;
    vector<Camel> camels_r;
    for (int j = 0; j < N; j++) {
      long long K, L, R;
      cin >> K;
      cin >> L;
      cin >> R;

      const long long D = L - R;
      if (D >= 0) {
        camels_l.push_back(Camel(D, L, R, K));
      } else {
        camels_r.push_back(Camel(-D, R, L, N - K));
      }
    }

    cout << calc(st, camels_l) + calc(st, camels_r) << endl;
  }

  return 0;
}