Problem p00362 (C++) — buggy submission, verdict: Runtime Error


#include <algorithm>
#include <array>
#include <chrono>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int llint;
typedef long double lld;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define dme                                                                    \\
  cout << "-1" << endl;                                                        \\
  return 0
const int mod = 1000000007;
const int big = 1e9 + 10;
const long double pai = 3.141592653589793238462643383279502884197;
const long double eps = 1e-7;
template <class T, class U> void mineq(T &a, U b) {
  if (a > b) {
    a = b;
  }
}
template <class T, class U> void maxeq(T &a, U b) {
  if (a < b) {
    a = b;
  }
}
llint gcd(llint a, llint b) {
  if (a % b == 0) {
    return b;
  } else
    return gcd(b, a % b);
}
llint lcm(llint a, llint b) { return a / gcd(a, b) * b; }
class HL {
public:
  int n;
  vector<vector<int>>
      ko;          //???????????£??\\??????,do_HL??????????????§???????????????
  vector<int> oya; //????????????
  //????????????????????????????????????????????????????????????
  vector<int> subsize;        //????????????????????????
  vector<pair<int, int>> dco; // heavy[dco[x].fir][dco[x].sec]=x
  vector<vector<int>> heavy;  // heavy pases ?????°??¨????????????????????????
  vector<int> light;          // light[x]=oya[heavy[x][0]];
  void reset(int in) {
    n = in;
    ko.res(n);
    oya.res(n);
    oya[0] = -1;
    subsize.res(n);
    dco.res(n);
  }
  HL(int in = 1) { reset(in); }
  void add_edge(int a, int b) { // a??????
    ko[a].pub(b);
    oya[b] = a;
  }
  int con_sub(int ter = 0) {
    int ans = 1;
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      ans += con_sub(*it);
    }
    subsize[ter] = ans;
    return ans;
  }
  void HL_solve(int ter = 0) {
    auto heitr = ko[ter].begin();
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      if (subsize[*it] > subsize[*heitr]) {
        heitr = it;
      }
    }
    dco[ter] = mp(heavy.size() - 1, heavy.back().size());
    heavy.back().pub(ter);
    if (ko[ter].size() > 0) {
      HL_solve(*heitr);
    }
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      if (it == heitr) {
        continue;
      }
      heavy.pub(vector<int>()); //??????pub
      light.pub(ter);
      HL_solve(*it);
    }
  }
  void do_HL(void) {
    // make_tree();
    con_sub();
    heavy.pub(vector<int>()); //??????pub
    light.pub(-1);
    HL_solve();
  }
};
template <typename T> class seg_tree { // rmq
public:
  T treemin;
  int seghi, segmg;
  seg_tree *left;
  seg_tree *right;
  void reset(int hi, int mg) { //??????????????????????????¶????????????
    treemin = 0;
    seghi = hi;
    segmg = mg;
    left = NULL;
    right = NULL;
    int tyu = (hi + mg) / 2;
    if (hi + 1 < mg) {
      make_left(hi, tyu);
      make_right(tyu, mg);
    }
  }
  seg_tree(int hi = 0, int mg = 0) { reset(hi, mg); }

  ~seg_tree() {
    delete left;
    delete right;
  }
  void make_left(int hi, int mg) { this->left = new seg_tree(hi, mg); }
  void make_right(int hi, int mg) { this->right = new seg_tree(hi, mg); }
  void setval(int pla, T val) { // pla???????´????val????????????
    if (seghi == pla && segmg == pla + 1) {
      treemin = val;
      return;
    }
    if (pla < left->segmg) {
      left->setval(pla, val);
    } else {
      right->setval(pla, val);
    }
    treemin = min(left->treemin, right->treemin);
  }
  T seg_ask(int hi, int mg) {
    if (hi <= seghi && segmg <= mg) {
      return treemin;
    }
    if (mg <= seghi || segmg <= hi) {
      return big;
    }
    T leret, riret;
    leret = left->seg_ask(hi, mg);
    riret = right->seg_ask(hi, mg);
    return min(leret, riret);
  }
};
template <class T> class BIT { //??£??????BIT??§??????
public:
  int kai;
  vector<T> val;
  BIT(int in = 0) { reset(in); }
  void reset(int in) {
    kai = 0;
    while ((1 << kai) < in) {
      kai++;
    }
    val.res(1 << kai);
  } //??????????????????????????¶????????????
  void BIT_add(int bas, T pla) {
    int now = bas + (1 << kai);
    int bi = 0;
    while (now) {
      now /= 2;
      if (bas & (1 << bi)) {
        val[now] += pla;
      }
      bi++;
    }
  }
  T BIT_ask(int bas) {
    T ans = 0;
    int now = bas + (1 << kai);
    int bi = 0;
    while (now) {
      now /= 2;
      if ((bas & (1 << bi)) == 0) {
        ans += val[now];
      }
      bi++;
    }
    return ans;
  }
};
class Euler_tourist { //???tourist???
                      //????????????????????????????????????
                      // tourist????????§?????????????????????
  //????????????????????¨?????±??????????????§????????????????????????
  //????????????????????????rsq???????????¨?????¨??????????¶????????????????
  //?????¨????????°?????????????????§?????????????
  // LCA?????????
  //??¨?????????????????????????????????????????????????????????????????????????????????
  //??¨?¨?????????????????????§??????????§£????????????
public:
  int n, now, nowrmq, K;
  vector<int> num; //????????????->??°????????????

  vector<int> gormq; // rmq??????????????¨??????
  seg_tree<int> rmq; //??????rmq?????¨?????¨LCA????????????

  vector<int> gobit; //?????°???????????¨???????????§?????????
  BIT<llint> cosbit; //??¨?????¨??????????¶??????????

  vector<pair<int, llint>> oya;        //??°??????????????????
  vector<vector<pair<int, llint>>> ko; //??°??????????????????

  HL hal;
  vector<llint> build; //?¢??????????

  vector<pair<int, llint>> oldoya; //????????????
  vector<vector<pair<int, llint>>>
      oldko; //???????????£??\\??????,do_Euler??????????????§???????????????,????????????
  Euler_tourist(int in) {
    n = in;
    now = 0;
    nowrmq = 0;
    num.res(n);
    gormq.res(n);
    rmq.reset(0, 2 * n - 1);
    gobit.res(n);
    cosbit.reset(n);
    oya.res(n);
    ko.res(n);
    oldoya.res(n);
    oldko.res(n);
    hal.reset(n);
    build.res(n);
  }
  void add_edge(int a, int b, llint c) {
    oldko[a].pub(mp(b, c));
    oldko[b].pub(mp(a, c));
  }
  void make_tree(int ter = 0,
                 int per = -1) { // make_tree(root);??§??¨????????????
    auto itr = oldko[ter].begin();
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      if (it->fir == per) {
        itr = it;
      }
    }
    if (per != -1) {
      oldoya[ter] = (*itr);
      oldko[ter].erase(itr);
    } else {
      oldoya[ter] = mp(-1, (llint)0);
    }
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      make_tree(it->fir, ter);
    }
  }
  void solve_Euler(int ter = 0) {
    // newnum.pub(ter);
    num[ter] = now;
    rmq.setval(nowrmq, num[ter]);
    gormq[num[ter]] = nowrmq;
    now++;
    nowrmq++;
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      solve_Euler(it->fir);
      rmq.setval(nowrmq, num[ter]);
      nowrmq++;
    }
    gobit[num[ter]] = now;
  }

  int find_LCA(int a, int b) {
    if (a > b) {
      swap(a, b);
    }
    return rmq.seg_ask(gormq[a], gormq[b] + 1);
  }
  void add_cost_oya(int a, int val) { //???????????¨????????????????¶????
    cosbit.BIT_add(gobit[a], val);
    cosbit.BIT_add(a, -val);
    // cost?????´??°?????????????????????
  }
  void add_cost_K(int a, int val) {
    llint kasa = 0;
    if (oya[a].sec % K != 0) {
      kasa -= oya[a].sec;
    }
    oya[a].sec += val;
    if (oya[a].sec % K != 0) {
      kasa += oya[a].sec;
    }
    add_cost_oya(a, kasa);
  }
  void addque(int x, int d) {
    build[x] += d;
    if (hal.heavy[hal.dco[x].fir].size() > hal.dco[x].sec + 1) {
      // HL???????????????
      int ha = hal.heavy[hal.dco[x].fir][hal.dco[x].sec + 1];
      add_cost_K(ha, d);
    }
    if (x > 0 && hal.dco[x].sec > 0) {
      add_cost_K(x, d);
    } // HL???????????????
  }
  llint sendque(int s, int t) {
    int tyu = find_LCA(s, t);
    return sendhan(tyu, s) + sendhan(tyu, t);
  }
  llint sendhan(int u, int s) { // u??????
    int gen = s;                //?????¨??????
    llint ans = cosbit.BIT_ask(s) - cosbit.BIT_ask(u);
    while (true) {
      int ima = hal.heavy[hal.dco[gen].fir][0];
      if (u >= ima) {
        break;
      }
      gen = oya[ima].fir;
      int thiscos = oya[ima].sec + build[ima] + build[gen];
      if (thiscos % K != 0) {
        ans += thiscos;
      }
    }
    return ans;
  }
  void do_Euler(void) {
    make_tree();
    solve_Euler();
    for (int i = 0; i < n; i++) {
      if (i != 0) {
        oya[num[i]] = mp(num[oldoya[i].fir], oldoya[i].sec);
      } else {
        oya[num[i]] = mp(-1, (llint)0);
      }
      for (auto itj = oldko[i].begin(); itj != oldko[i].end(); itj++) {
        ko[i].pub(mp(num[itj->fir], itj->sec));
      }
    }
    for (int i = 1; i < n; i++) {
      hal.add_edge(oya[i].fir, i);
    }
    hal.do_HL();
    for (int i = 1; i < n; i++) {
      if (oya[i].sec % K == 0) {
        continue;
      }
      if (hal.dco[i].sec > 0) {
        add_cost_oya(i, oya[i].sec);
      } // HL???????????????
    }
  }
};
int main(void) {
  int i, n, k;
  cin >> n >> k;
  Euler_tourist yutaka_tourist_rng(n);
  yutaka_tourist_rng.K = k;
  for (i = 0; i < n - 1; i++) {
    int a, b;
    llint c;
    cin >> a >> b >> c;
    yutaka_tourist_rng.add_edge(a, b, c);
  }
  yutaka_tourist_rng.do_Euler();
  int q;
  cin >> q;
  while (q--) {
    string str;
    cin >> str;
    if (str == "add") {
      int x, d;
      cin >> x >> d;
      x = yutaka_tourist_rng.num[x];
      yutaka_tourist_rng.addque(x, d);
    } else {
      int s, t;
      cin >> s >> t;
      s = yutaka_tourist_rng.num[s];
      t = yutaka_tourist_rng.num[t];
      cout << yutaka_tourist_rng.sendque(s, t) << endl;
    }
  }
  return 0;
}

Error: 0

Fixed submission:


#include <algorithm>
#include <array>
#include <chrono>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int llint;
typedef long double lld;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define dme                                                                    \\
  cout << "-1" << endl;                                                        \\
  return 0
const int mod = 1000000007;
const llint big = 1e9 + 10;
const long double pai = 3.141592653589793238462643383279502884197;
const long double eps = 1e-7;
template <class T, class U> void mineq(T &a, U b) {
  if (a > b) {
    a = b;
  }
}
template <class T, class U> void maxeq(T &a, U b) {
  if (a < b) {
    a = b;
  }
}
llint gcd(llint a, llint b) {
  if (a % b == 0) {
    return b;
  } else
    return gcd(b, a % b);
}
llint lcm(llint a, llint b) { return a / gcd(a, b) * b; }
class HL {
public:
  int n;
  vector<vector<int>>
      ko;          //???????????£??\\??????,do_HL??????????????§???????????????
  vector<int> oya; //????????????
  //????????????????????????????????????????????????????????????
  vector<int> subsize;        //????????????????????????
  vector<pair<int, int>> dco; // heavy[dco[x].fir][dco[x].sec]=x
  vector<vector<int>> heavy;  // heavy pases ?????°??¨????????????????????????
  vector<int> light;          // light[x]=oya[heavy[x][0]];
  void reset(int in) {
    n = in;
    ko.res(n);
    oya.res(n);
    oya[0] = -1;
    subsize.res(n);
    dco.res(n);
  }
  HL(int in = 1) { reset(in); }
  void add_edge(int a, int b) { // a??????
    ko[a].pub(b);
    oya[b] = a;
  }
  int con_sub(int ter = 0) {
    int ans = 1;
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      ans += con_sub(*it);
    }
    subsize[ter] = ans;
    return ans;
  }
  void HL_solve(int ter = 0) {
    auto heitr = ko[ter].begin();
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      if (subsize[*it] > subsize[*heitr]) {
        heitr = it;
      }
    }
    dco[ter] = mp(heavy.size() - 1, heavy.back().size());
    heavy.back().pub(ter);
    if (ko[ter].size() > 0) {
      HL_solve(*heitr);
    }
    for (auto it = ko[ter].begin(); it != ko[ter].end(); it++) {
      if (it == heitr) {
        continue;
      }
      heavy.pub(vector<int>()); //??????pub
      light.pub(ter);
      HL_solve(*it);
    }
  }
  void do_HL(void) {
    // make_tree();
    con_sub();
    heavy.pub(vector<int>()); //??????pub
    light.pub(-1);
    HL_solve();
  }
};
template <typename T> class seg_tree { // rmq
public:
  T treemin;
  int seghi, segmg;
  seg_tree *left;
  seg_tree *right;
  void reset(int hi, int mg) { //??????????????????????????¶????????????
    treemin = 0;
    seghi = hi;
    segmg = mg;
    left = NULL;
    right = NULL;
    int tyu = (hi + mg) / 2;
    if (hi + 1 < mg) {
      make_left(hi, tyu);
      make_right(tyu, mg);
    }
  }
  seg_tree(int hi = 0, int mg = 0) { reset(hi, mg); }

  ~seg_tree() {
    delete left;
    delete right;
  }
  void make_left(int hi, int mg) { this->left = new seg_tree(hi, mg); }
  void make_right(int hi, int mg) { this->right = new seg_tree(hi, mg); }
  void setval(int pla, T val) { // pla???????´????val????????????
    if (seghi == pla && segmg == pla + 1) {
      treemin = val;
      return;
    }
    if (pla < left->segmg) {
      left->setval(pla, val);
    } else {
      right->setval(pla, val);
    }
    treemin = min(left->treemin, right->treemin);
  }
  T seg_ask(int hi, int mg) {
    if (hi <= seghi && segmg <= mg) {
      return treemin;
    }
    if (mg <= seghi || segmg <= hi) {
      return big;
    }
    T leret, riret;
    leret = left->seg_ask(hi, mg);
    riret = right->seg_ask(hi, mg);
    return min(leret, riret);
  }
};
template <class T> class BIT { //??£??????BIT??§??????
public:
  int kai;
  vector<T> val;
  BIT(int in = 0) { reset(in); }
  void reset(int in) {
    kai = 0;
    while ((1 << kai) < in) {
      kai++;
    }
    val.res(1 << kai);
  } //??????????????????????????¶????????????
  void BIT_add(int bas, T pla) {
    int now = bas + (1 << kai);
    int bi = 0;
    while (now) {
      now /= 2;
      if (bas & (1 << bi)) {
        val[now] += pla;
      }
      bi++;
    }
  }
  T BIT_ask(int bas) {
    T ans = 0;
    int now = bas + (1 << kai);
    int bi = 0;
    while (now) {
      now /= 2;
      if ((bas & (1 << bi)) == 0) {
        ans += val[now];
      }
      bi++;
    }
    return ans;
  }
};
class Euler_tourist { //???tourist???
                      //????????????????????????????????????
                      // tourist????????§?????????????????????
  //????????????????????¨?????±??????????????§????????????????????????
  //????????????????????????rsq???????????¨?????¨??????????¶????????????????
  //?????¨????????°?????????????????§?????????????
  // LCA?????????
  //??¨?????????????????????????????????????????????????????????????????????????????????
  //??¨?¨?????????????????????§??????????§£????????????
public:
  int n, now, nowrmq, K;
  vector<int> num; //????????????->??°????????????

  vector<int> gormq; // rmq??????????????¨??????
  seg_tree<int> rmq; //??????rmq?????¨?????¨LCA????????????

  vector<int> gobit; //?????°???????????¨???????????§?????????
  BIT<llint> cosbit; //??¨?????¨??????????¶??????????

  vector<pair<int, llint>> oya;        //??°??????????????????
  vector<vector<pair<int, llint>>> ko; //??°??????????????????

  HL hal;
  vector<llint> build; //?¢??????????

  vector<pair<int, llint>> oldoya; //????????????
  vector<vector<pair<int, llint>>>
      oldko; //???????????£??\\??????,do_Euler??????????????§???????????????,????????????
  Euler_tourist(int in) {
    n = in;
    now = 0;
    nowrmq = 0;
    num.res(n);
    gormq.res(n);
    rmq.reset(0, 2 * n - 1);
    gobit.res(n);
    cosbit.reset(n);
    oya.res(n);
    ko.res(n);
    oldoya.res(n);
    oldko.res(n);
    hal.reset(n);
    build.res(n);
  }
  void add_edge(int a, int b, llint c) {
    oldko[a].pub(mp(b, c));
    oldko[b].pub(mp(a, c));
  }
  void make_tree(int ter = 0,
                 int per = -1) { // make_tree(root);??§??¨????????????
    auto itr = oldko[ter].begin();
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      if (it->fir == per) {
        itr = it;
      }
    }
    if (per != -1) {
      oldoya[ter] = (*itr);
      oldko[ter].erase(itr);
    } else {
      oldoya[ter] = mp(-1, (llint)0);
    }
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      make_tree(it->fir, ter);
    }
  }
  void solve_Euler(int ter = 0) {
    // newnum.pub(ter);
    num[ter] = now;
    rmq.setval(nowrmq, num[ter]);
    gormq[num[ter]] = nowrmq;
    now++;
    nowrmq++;
    for (auto it = oldko[ter].begin(); it != oldko[ter].end(); it++) {
      solve_Euler(it->fir);
      rmq.setval(nowrmq, num[ter]);
      nowrmq++;
    }
    gobit[num[ter]] = now;
  }

  int find_LCA(int a, int b) { return rmq.seg_ask(gormq[a], gormq[b] + 1); }
  void add_cost_oya(int a, int val) { //???????????¨????????????????¶????
    cosbit.BIT_add(gobit[a], val);
    cosbit.BIT_add(a, -val);
    // cost?????´??°?????????????????????
  }
  void add_cost_K(int a, int val) {
    llint kasa = 0;
    if (oya[a].sec % K != 0) {
      kasa -= oya[a].sec;
    }
    oya[a].sec += val;
    if (oya[a].sec % K != 0) {
      kasa += oya[a].sec;
    }
    add_cost_oya(a, kasa);
  }
  void addque(int x, int d) {
    build[x] += d;
    if (hal.heavy[hal.dco[x].fir].size() > hal.dco[x].sec + 1) {
      // HL???????????????
      int ha = hal.heavy[hal.dco[x].fir][hal.dco[x].sec + 1];
      add_cost_K(ha, d);
    }
    if (x > 0 && hal.dco[x].sec > 0) {
      add_cost_K(x, d);
    } // HL???????????????
  }
  llint sendque(int s, int t) {
    int tyu = find_LCA(s, t);
    return sendhan(tyu, s) + sendhan(tyu, t);
  }
  llint sendhan(int u, int s) { // u??????
    int gen = s;                //?????¨??????
    llint ans = cosbit.BIT_ask(s) - cosbit.BIT_ask(u);
    while (true) {
      int ima = hal.heavy[hal.dco[gen].fir][0];
      if (u >= ima) {
        break;
      }
      gen = oya[ima].fir;
      int thiscos = oya[ima].sec + build[ima] + build[gen];
      if (thiscos % K != 0) {
        ans += thiscos;
      }
    }
    return ans;
  }
  void do_Euler(void) {
    make_tree();
    solve_Euler();
    for (int i = 0; i < n; i++) {
      if (i != 0) {
        oya[num[i]] = mp(num[oldoya[i].fir], oldoya[i].sec);
      } else {
        oya[num[i]] = mp(-1, (llint)0);
      }
      for (auto itj = oldko[i].begin(); itj != oldko[i].end(); itj++) {
        ko[i].pub(mp(num[itj->fir], itj->sec));
      }
    }
    for (int i = 1; i < n; i++) {
      hal.add_edge(oya[i].fir, i);
    }
    hal.do_HL();
    for (int i = 1; i < n; i++) {
      if (oya[i].sec % K == 0) {
        continue;
      }
      if (hal.dco[i].sec > 0) {
        add_cost_oya(i, oya[i].sec);
      } // HL???????????????
    }
  }
};
int main(void) {
  int i, n, k;
  cin >> n >> k;
  Euler_tourist yutaka_tourist_rng(n);
  yutaka_tourist_rng.K = k;
  for (i = 0; i < n - 1; i++) {
    int a, b;
    llint c;
    cin >> a >> b >> c;
    yutaka_tourist_rng.add_edge(a, b, c);
  }
  yutaka_tourist_rng.do_Euler();
  int q;
  cin >> q;
  while (q--) {
    string str;
    cin >> str;
    if (str == "add") {
      int x, d;
      cin >> x >> d;
      x = yutaka_tourist_rng.num[x];
      yutaka_tourist_rng.addque(x, d);
    } else {
      int s, t;
      cin >> s >> t;
      s = yutaka_tourist_rng.num[s];
      t = yutaka_tourist_rng.num[t];
      cout << yutaka_tourist_rng.sendque(s, t) << endl;
    }
  }
  return 0;
}