La matriz de árbol mantiene el subárbol y

Enlace del título

Problema

\ (Se sabe que hay n nodos con n − 1 aristas, formando una estructura de árbol \) .

\ (Dado un nodo raíz k, cada nodo tiene un peso, y el peso del nodo i es vi \)

\ (Para m operaciones, hay dos tipos de operaciones: \)

\ (1 \ space a \ space x: significa agregar el peso del nodo a a x \)

\ (2 \ espacio a: significa la suma de todos los nodos en el subárbol del nodo a (incluido el nodo a)) \)

Solución

\ (Hay una conclusión: la marca de tiempo dfn de un nodo y todos sus nodos de subárbol es continua \)

\ (Usamos una marca de tiempo dfn, hora1 cuando ingresamos, hora2 \ después de atravesar todos los nodos de subárbol)

\ (Entonces, el rango de este nodo y todos sus nodos de subárbol es un tiempo continuo1-tiempo2, entonces puede usar la matriz de árbol para mantener \)

\ (Es decir, a través de la marca de tiempo dfn (orden dfs), convierta el árbol en un segmento lineal continuo \)

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
ll val[maxn];
ll valu[maxn];
vector<int>E[maxn];
int dfn[maxn],ed[maxn];
int cnt;
int n,m,k;
int lowbit(int x){
    return x&-x;
}
void add(int x,ll w){
    while(x<=n){
        val[x] += w;
        x += lowbit(x);
    }
}
ll query(int x){
    ll res = 0;
    while(x){
        res += val[x];
        x -= lowbit(x);
    }
    return res;
}
void dfs(int p,int fa){
    dfn[p] = cnt++; add(dfn[p],valu[p]);
    for(int i=0;i<(int)E[p].size();i++){
        int v = E[p][i];
        if(v!=fa){
            dfs(v,p);
        }
    }
    ed[p] = cnt-1;
}
int main(){
    IOS
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++) cin>>valu[i];
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        E[u].push_back(v);
        E[v].push_back(u);
    }
    cnt = 1;
    dfs(k,0);
    for(int i=1;i<=m;i++){
        int op,p;
        cin>>op>>p;
        if(op==1){
            ll w;
            cin>>w;
            add(dfn[p],w);
        }else{
            cout<<query(ed[p])-query(dfn[p]-1)<<endl;
        }
    }
    return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/Tianwell/p/12733086.html
Recomendado
Clasificación