#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;
}
ddd
发布时间 2023-08-15 08:42:06作者: Tagaki