调不出来惹
查看原帖
调不出来惹
481621
Zhang_Wenjie楼主2024/10/17 16:59

样例都没过 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;
}
2024/10/17 16:59
加载中...