样例都没过 qwq,还有吸氧会 T?不吸氧就不会。。
#include <bits/stdc++.h>
#define re register int
#define lp p << 1
#define rp p << 1 | 1
using namespace std;
const int N = 5e4 + 10, mod = 201314;
struct Edge
{
int to, next;
}e[N << 1];
int idx, h[N];
struct Tree
{
int l, r, sum, tag;
}t[N << 2];
int n, m, id[N], cnt;
int fa[N], son[N], dep[N], siz[N], top[N];
struct Query
{
int id, pos, z, type;
}q[N];
int num, ans[N];
bool cmp(Query i, Query j) { return i.pos < j.pos; }
inline void add(int x, int y)
{
e[++ idx] = (Edge){y, h[x]};
h[x] = idx;
}
void dfs(int u, int fu)
{
fa[u] = fu;
dep[u] = dep[fu] + 1;
siz[u] = 1;
for (re i = h[u]; i; i = e[i].next)
{
int v = e[i].to;
if (v == fu) continue;
dfs(v, u);
siz[u] += siz[v];
if (siz[son[u]] < siz[v]) son[u] = v;
}
}
void mark(int u, int t)
{
top[u] = t;
id[u] = ++ cnt;
if (son[u]) mark(son[u], t);
for (re i = h[u]; i; i = e[i].next)
{
int v = e[i].to;
if (v == fa[u] || v == son[u]) continue;
mark(v, v);
}
}
inline void push_down(int p)
{
if (t[p].tag)
{
t[lp].sum += (t[lp].r - t[lp].l + 1) * t[p].tag % mod;
t[rp].sum += (t[rp].r - t[rp].l + 1) * t[p].tag % mod;
t[lp].tag += t[p].tag;
t[rp].tag += t[p].tag;
t[p].tag = 0;
}
}
inline void build(int p, int l, int r)
{
t[p].l = l, t[p].r = r;
if (l == r) return;
int mid = (l + r) >> 1;
build(lp, l, mid);
build(rp, mid + 1, r);
}
inline void update(int p, int l, int r, int k)
{
if (l <= t[p].l && t[p].r <= r)
{
t[p].sum += (t[p].r - t[p].l + 1) * k % mod;
t[p].tag += k;
return;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) update(lp, l, r, k);
if (r > mid) update(rp, l, r, k);
t[p].sum = (t[lp].sum + t[rp].sum) % mod;
}
inline int query(int p, int l, int r)
{
if (l <= t[p].l && t[p].r <= r) return t[p].sum;
push_down(p);
int res = 0;
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) res += query(lp, l, r) % mod;
if (r > mid) res += query(rp, l, r) % mod;
return res % mod;
}
inline void update_path(int u, int v)
{
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]]) swap(u, v);
update(1, id[top[u]], top[u], 1);
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
update(1, id[v], id[u], 1);
}
inline int query_path(int u, int v)
{
int res = 0;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]]) swap(u, v);
res += query(1, id[top[u]], top[u]) % mod;
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
res += query(1, id[v], id[u]) % mod;
return res % mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (re i = 2; i <= n; i ++)
{
int x; cin >> x;
x ++;
add(x, i), add(i, x);
}
dfs(1, 0); mark(1, 1);
build(1, 1, n);
for (re i = 1; i <= m; i ++)
{
int l, r, z; cin >> l >> r >> z;
l ++, r ++, z ++;
q[++ num].id = i, q[num].pos = l - 1, q[num].z = z, q[num].type = -1;
q[++ num].id = i, q[num].pos = r, q[num].z = z, q[num].type = 1;
}
sort(q + 1, q + num + 1, cmp);
int j = 1;
for (re i = 1; i <= num; i ++)
{
while (j <= q[i].pos) update_path(1, j ++);
ans[q[i].id] = (ans[q[i].id] + query_path(1, q[i].z) * q[i].type + mod) % mod;
}
for (re i = 1; i <= m; i ++)
cout << ans[i] << '\n';
return 0;
}