一脸懵逼,写了个动态开点权值线段树然后RE了。。。空间明明开够了啊。。。
还是说我对动态开点有什么误解。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
inline void read(T &x){
x = 0;int fu = 1;
char c = getchar();
while(c > 57 || c < 48){
if(c == 45) fu = -1;
c = getchar();
}
while(c <= 57 && c >= 48){
x = (x << 3) + (x << 1) + c - 48;
c = getchar();
}
x *= fu;
}
template <typename T>
inline void fprint(T x){
if(x < 0) putchar(45), x = -x;
if(x > 9) fprint(x / 10);
putchar(x % 10 + 48);
}
template <typename T>
inline void fprint(T x, char ch){
fprint(x);putchar(ch);
}
inline char next_char(){
char ch = getchar();
while(ch == 9 || ch == 10 || ch == 32) ch = getchar();
return ch;
}
template <typename T>
inline T mn(T x, T y) {return x < y ? x : y;}
template <typename T>
inline T mx(T x, T y) {return x > y ? x : y;}
template <typename T>
inline void chmin(T &x, T y) {(x > y) && (x = y);}
template <typename T>
inline void chmax(T &x, T y) {(x < y) && (x = y);}
#define MAXN 150005
int n, q, A;
int head[MAXN], e[MAXN << 1], nxt[MAXN << 1], cnt, val[MAXN << 1];
inline void add(int u, int v, int w){
nxt[++ cnt] = head[u];
head[u] = cnt;
e[cnt] = v;
val[cnt] = w;
}
int sz[MAXN], SZ[MAXN], fa[MAXN];
int root, Root;
int dep[MAXN], anc[MAXN][21], dis[MAXN];
void dfs(int x, int pre){
dep[x] = dep[pre] + 1;
for (register int i = head[x];i;i = nxt[i]){
if(e[i] == pre) continue;
anc[e[i]][0] = x;
dis[e[i]] = dis[x] + val[i];
for (register int j = 1;j <= 20;j ++) anc[e[i]][j] = anc[anc[e[i]][j - 1]][j - 1];
dfs(e[i], x);
}
}
inline int LCA(int x, int y){
if(dep[x] < dep[y]) swap(x, y);
for (register int i = 20;i >= 0;i --){
if(dep[anc[x][i]] >= dep[y]) x = anc[x][i];
if(dep[x] == dep[y]) break;
}
if(x == y) return x;
for (register int i = 20;i >= 0;i --){
if(anc[x][i] ^ anc[y][i]){
x = anc[x][i];
y = anc[y][i];
}
}
return anc[x][0];
}
inline int dist(int x, int y){return dis[x] + dis[y] - (dis[LCA(x, y)] << 1);}
bool vis[MAXN];
void getsz(int x, int pre){
sz[x] = 1;
for (register int i = head[x];i;i = nxt[i]){
if(e[i] == pre || vis[e[i]]) continue;
getsz(e[i], x);
sz[x] += sz[e[i]];
}
}
void getroot(int x, int pre, int rt){
SZ[x] = 0;
for (register int i = head[x];i;i = nxt[i]){
if(e[i] == pre || vis[e[i]]) continue;
getroot(e[i], x, rt);
chmax(SZ[x], sz[e[i]]);
}
chmax(SZ[x], sz[rt] - sz[x]);
if(SZ[x] < SZ[root]) root = x;
}
void dfz(int x){
vis[x] = 1;
for (register int i = head[x];i;i = nxt[i]){
if(vis[e[i]]) continue;
getsz(e[i], x);
root = 0;
getroot(e[i], x, e[i]);
fa[root] = x;
dfz(root);
}
}
struct DPair{
LL sig;int cc;
inline DPair operator + (const DPair &b) const{
DPair ret;
ret.sig = sig + b.sig;
ret.cc = cc + b.cc;
return ret;
}
inline DPair operator - (const DPair &b) const{
DPair ret;
ret.sig = sig - b.sig;
ret.cc = cc - b.cc;
return ret;
}
}t[MAXN * 135];
int lc[MAXN * 135], rc[MAXN * 135];
int t1[MAXN], t2[MAXN], tot, Tot;
#define RANGE 1, Tot
int a[MAXN];
#define LSON lc[rt], l, mid
#define RSON rc[rt], mid + 1, r
void modify(int &rt, int l, int r, int x, int y){
if(!rt) rt = ++ tot;
t[rt].sig += y;t[rt].cc ++;
if(l == r) return ;
int mid = (l + r) >> 1;
if(x <= mid) modify(LSON, x, y);
else modify(RSON, x, y);
}
DPair query(int rt, int l, int r, int x, int y){
if(!rt) return (DPair){0ll, 0};
if(x <= l && r <= y) return t[rt];
int mid = (l + r) >> 1;
if(x <= mid && y > mid) return query(LSON, x, y) + query(RSON, x, y);
if(x <= mid) return query(LSON, x, y);
else return query(RSON, x, y);
}
inline void Modify(int x, int w){
int cur = x;
while(cur){
modify(t1[cur], RANGE, w, dist(cur, x));
if(fa[cur]) modify(t2[cur], RANGE, w, dist(fa[cur], x));
cur = fa[cur];
}
}
inline LL Query(int x, int l, int r){
LL ret = 0;
int cur = x, pre = 0;
while(cur){
DPair res = query(t1[cur], RANGE, l, r);
if(pre) res = res - query(t2[pre], RANGE, l, r);
ret += res.sig;
ret += 1ll * res.cc * dist(x, cur);
pre = cur;
cur = fa[cur];
}
return ret;
}
int b[MAXN];
int main(){
SZ[0] = 0x3f3f3f3f;
read(n);read(q);read(A);
for (register int i = 1;i <= n;i ++) read(a[i]), b[i] = a[i];
sort(b + 1, b + n + 1);
Tot = unique(b + 1, b + n + 1) - b - 1;
for (register int i = 1;i < n;i ++){
int u, v, w;read(u);read(v);read(w);
add(u, v, w);add(v, u, w);
}
dfs(1, 0);
getsz(1, 0);
root = 0;
getroot(1, 0, 1);
Root = root;
dfz(Root);
for (register int i = 1;i <= n;i ++) a[i] = lower_bound(b + 1, b + Tot + 1, a[i]) - b, Modify(i, a[i]);
LL ans = 0;
while(q --){
LL l, r, u;read(u);read(l);read(r);
l = (l + ans) % A, r = (r + ans) % A;
if(l > r) swap(l, r);
l = lower_bound(b + 1, b + Tot + 1, l) - b;
r = upper_bound(b + 1, b + Tot + 1, r) - b - 1;
if(l > r) fprint(ans = 0ll, 10);
else fprint(ans = Query(u, l, r), 10);
}
}