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

2022杭电多校第二场 A.Static Query on Tree

2022杭电多校第二场 Slayers Come

2022杭电多校第二场 Slayers Come