2022杭电多校第二场 A.Static Query on Tree
Posted TURNINING
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022杭电多校第二场 A.Static Query on Tree相关的知识,希望对你有一定的参考价值。
维护四种标记
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
inline int read()
int k=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')f=-1;ch=getchar();
while(ch>='0'&&ch<='9')k=k*10+ch-'0';ch=getchar();
return k*f;
inline void write(int x)
if(x<0) putchar('-'),x=-x;
if(x>9)write(x/10);putchar(x%10+'0');
namespace segtree
#define lsn (u << 1)
#define rsn (u << 1 | 1)
#define mid (l + r >> 1)
struct Node
int c00, c01, c10, c11;
int tag1, tag2;
tr[MAXN << 2];
void init(int u, int l, int r)
tr[u].c00 = r - l + 1;
tr[u].c01 = tr[u].c10 = tr[u].c11 = 0;
tr[u].tag1 = 1; tr[u].tag2 = 0;
void pushup(int u)
tr[u].c00 = tr[lsn].c00 + tr[rsn].c00;
tr[u].c11 = tr[lsn].c11 + tr[rsn].c11;
tr[u].c01 = tr[lsn].c01 + tr[rsn].c01;
tr[u].c10 = tr[lsn].c10 + tr[rsn].c10;
void mov(int u, int s)
if(s == 1)
tr[u].c11 += tr[u].c10;
tr[u].c01 += tr[u].c00;
tr[u].c00 = tr[u].c10 = 0;
else if(s == 2)
tr[u].c11 += tr[u].c01;
tr[u].c10 += tr[u].c00;
tr[u].c00 = tr[u].c01 = 0;
else if(s == 3)
tr[u].c11 += tr[u].c10 + tr[u].c01 + tr[u].c00;
tr[u].c00 = tr[u].c01 = tr[u].c10 = 0;
tr[u].tag2 |= s;
void pushdown(int u, int l, int r)
if(tr[u].tag1)
init(lsn, l, mid);
init(rsn, mid+1, r);
if(tr[u].tag2)
mov(lsn, tr[u].tag2);
mov(rsn, tr[u].tag2);
tr[u].tag1 = tr[u].tag2 = 0;
void update(int u, int l, int r, int L, int R, int s)
if(L <= l && r <= R)
mov(u, s);
return ;
pushdown(u, l, r);
if(L <= mid) update(lsn, l, mid, L, R, s);
if(R > mid) update(rsn, mid+1, r, L, R, s);
pushup(u);
int query(int u, int l, int r, int L, int R)
if(L <= l && r <= R)
int res = tr[u].c11;
init(u, l, r);
return res;
pushdown(u, l, r);
int res = 0;
if(L <= mid) res += query(lsn, l, mid, L, R);
if(R > mid) res += query(rsn, mid+1, r, L, R);
pushup(u);
return res;
vector<int> g[MAXN];
int n, q, tot;
int val[MAXN];
int sz[MAXN], son[MAXN], top[MAXN], fa[MAXN], rnk[MAXN], dfsn[MAXN], dep[MAXN];
int l[MAXN], r[MAXN];
void dfs1(int u)
son[u] = -1;
sz[u] = 1;
for(auto v : g[u])
if(dep[v]) continue;
dep[v] = dep[u] + 1;
fa[v] = u;
dfs1(v);
sz[u] += sz[v];
if(son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v;
void dfs2(int u, int t)
top[u] = t;
l[u] = dfsn[u] = ++tot;
rnk[tot] = u;
if(son[u] == -1) r[u] = l[u]; return ;
dfs2(son[u], t);
for(auto v : g[u])
if(v != son[u] && v != fa[u]) dfs2(v, v);
r[u] = tot;
void update(int x, int y, int val)
int fx = top[x], fy = top[y];
while(fx != fy)
if(dep[fx] >= dep[fy]) segtree::update(1, 1, n, dfsn[fx], dfsn[x], val), x = fa[fx];
else segtree::update(1, 1, n, dfsn[fy], dfsn[y], val), y = fa[fy];
fx = top[x];
fy = top[y];
if(dfsn[x] < dfsn[y]) segtree::update(1, 1, n, dfsn[x], dfsn[y], val);
else segtree::update(1, 1, n, dfsn[y], dfsn[x], val);
void solve()
n = read(); q = read();
tot = 0;
for(int i = 1; i <= n; i++)
g[i].clear();
dep[i] = 0;
for(int i = 2; i <= n; i++)
int r = read();
g[r].push_back(i);
dep[1] = 1;
dfs1(1); dfs2(1, 1);
while(q--)
int A, B, C;
A = read(); B = read(); C = read();
segtree::init(1, 1, n);
for(int i = 1; i <= A; i++)
int u = read();
update(1, u, 1);
for(int i = 1; i <= B; i++)
int u = read();
update(1, u, 2);
int res = 0;
for(int i = 1; i <= C; i++)
int u = read();
res += segtree::query(1, 1, n, l[u], r[u]);
write(res); puts("");
int main()
int t; t = read();
while(t--)
solve();
以上是关于2022杭电多校第二场 A.Static Query on Tree的主要内容,如果未能解决你的问题,请参考以下文章
2022杭电多校第二场 A.Static Query on Tree(树剖)
2022杭电多校第二场 A.Static Query on Tree
2022杭电多校第二场 A.Static Query on Tree