ddd

发布时间 2023-08-15 08:42:06作者: Tagaki
#include <bits/stdc++.h>
#define file_in(x) (freopen(#x".in", "r", stdin))
#define file_out(x) (freopen(#x".out", "w", stdout))
#define ll long long
#define vi vector
#define pr pair <int, int>
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define db double

using namespace std;

char _c; bool _f; template <class T> void IN(T &x) {
  _f = x = 0; while (_c = getchar(), !isdigit(_c)) {if (_c == '-') _f = 1;}
  while (isdigit(_c)) {x = x * 10 + _c - '0', _c = getchar();} if (_f) x = -x;
}

template <class T> void _write(T x) {
  if (x < 0) return putchar('-'), _write(-x);
  if (x > 9) _write(x / 10);
  putchar('0' + x % 10);
}
template <class T> void write(T x) {_write(x), putchar('\n');}
template <class T> void write_s(T x) {_write(x), putchar(' ');}
template <class first, class... rest> void write(first fir, rest... res) {
  write_s(fir), write(res...);
}
#define debug(...) (_debug(#__VA_ARGS__, __VA_ARGS__))
template <class T> void _debug(const char *format, T x) {
  cerr << format << " = " << x << endl;
}
template <class first, class... rest>
void _debug(const char *format, first fir, rest... res) {
  while (*format != ',') cerr << *format++;
  cerr << " = " << fir << ",", _debug(format + 1, res...);
}

bool START;

const int N = 2e5 + 5;

int n, Q, A, a[N], di[N], dep[N], mx[N], sz[N], rt, f[N], dfn[N], dn, mi[20][N], lg[N];
ll ans;

struct edge {
  int y, w;
};

vi <edge> G[N];
vi <int> b[N];
vi <ll> s1[N], s2[N];
bool vis[N];

int END;

void add_e(int x, int y, int w) {G[x].pb((edge) {y, w});}

int get(int x, int y) {return dep[x] < dep[y] ? x : y;}

void dfs(int x, int fa) {
  dfn[x] = ++dn, mi[0][dn] = fa, dep[x] = dep[fa] + 1;
  for (auto e : G[x]) {
    int y = e.y, w = e.w; if (y == fa) continue;
    di[y] = di[x] + w, dfs(y, x);
  }
}

int lca(int x, int y) {
  if (x == y) return x;
  if ((x = dfn[x]) > (y = dfn[y])) swap(x, y);
  int d = lg[y - x];
  return get(mi[d][x + 1], mi[d][y - (1 << d) + 1]);
}

int dis(int x, int y) {return di[x] + di[y] - 2 * di[lca(x, y)];}

void find_rt(int x, int fa, int tot) {
  sz[x] = 1, mx[x] = 0;
  for (auto e : G[x]) {
    int y = e.y, w = e.w; if (y == fa || vis[y]) continue;
    find_rt(y, x, tot), sz[x] += sz[y], mx[x] = max(mx[x], sz[y]);
  }
  mx[x] = max(mx[x], tot - sz[x]);
  if (mx[x] < mx[rt]) rt = x;
}

void dfs2(int x, int fa, int anc) {
  b[anc].pb(x), sz[x] = 1;
  for (auto e : G[x]) {
    int y = e.y, w = e.w; if (y == fa || vis[y]) continue;
    dfs2(y, x, anc), sz[x] += sz[y];
  }
}

bool cmp(int x, int y) {return a[x] < a[y];}

void divi(int u, int siz) {
  b[u].pb(0), b[u].pb(u), s1[u].resize(siz + 5), s2[u].resize(siz + 5), vis[u] = 1;
  for (auto e : G[u]) {
    int y = e.y; if (vis[y]) continue;
    dfs2(y, u, u);
  }
  sort(b[u].begin(), b[u].end(), cmp);
  for (int i = 1; i < b[u].size(); ++i) {
    s1[u][i] = s1[u][i - 1] + dis(b[u][i], u), s2[u][i] = s2[u][i - 1] + dis(b[u][i], f[u]);
  }
  for (int i = 1; i < b[u].size(); ++i) b[u][i] = a[b[u][i]];
  for (auto e : G[u]) {
    int y = e.y; if (vis[y]) continue;
    rt = 0, find_rt(y, u, sz[y]), f[rt] = u, divi(rt, sz[y]);
  }
}

void cl(int u, int l, int r, int t) {
  int fa = f[u];
  int L = lower_bound(b[u].begin() + 1, b[u].end(), l) - b[u].begin();
  int R = upper_bound(b[u].begin() + 1, b[u].end(), r) - b[u].begin() - 1;
  ans += s1[u][R] - s1[u][L - 1];
  ans += 1ll * dis(u, t) * (R - L + 1);
  if (fa) {
    ans -= 1ll * dis(fa, t) * (R - L + 1);
    ans -= (s2[u][R] - s2[u][L - 1]);
    cl(fa, l, r, t);
  }
}

signed main() {
  IN(n), IN(Q), IN(A); for (int i = 1; i <= n; ++i) IN(a[i]), a[i]++;
  for (int i = 1, x, y, w; i < n; ++i) IN(x), IN(y), IN(w), add_e(x, y, w), add_e(y, x, w);
  mx[0] = n, dfs(1, 0);
  for (int i = 2; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
  for (int i = 1; (1 << i) <= n; ++i)
    for (int j = 1; j + (1 << i) - 1 <= n; ++j)
      mi[i][j] = get(mi[i - 1][j], mi[i - 1][j + (1 << (i - 1))]);
  find_rt(1, 0, n), divi(rt, n);
  while (Q--) {
    int u, l, r; IN(u), IN(l), IN(r);
    int L = min((l + ans) % A, (r + ans) % A), R = max((l + ans) % A, (r + ans) % A);
    L++, R++, ans = 0, cl(u, L, R, u), write(ans);
  }
  return 0;
}