dfs序题集

dfs序可以维护一个子树内的信息

需要记录dfs进的时间以及所有子树都遍历完的时间

void dfs(int u, int fa)
{
    L[u] = ++id;
    for(int i = head[u]; ~i; i = e[i].next)
    {
        int v = e[i].to;
        if(v == fa) continue;
        dfs(v, u);
    }
    R[u] = id;
}

那么对于点i,L[i]到R[i]就是i的子树(包括i)

那么子树内维护信息就可以用树状数组,线段树之内的乱搞了。

poj 3321

用树状数组维护就好。

注意修改的时候一定是修改序列

#include<cstdio>
#include<cstring>
#include<cctype>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
 
const int MAXN = 1e5 + 10;
struct Edge{ int to, next; };
Edge e[MAXN << 1];
int head[MAXN], num, n, m;
int L[MAXN], R[MAXN], s[MAXN], id;

struct Binary_Index_Tree
{
    int f[MAXN];
    
    Binary_Index_Tree() { memset(f, 0, sizeof(f)); }
    
    int lowbit(int x) { return x & (-x); }
    
    void add(int x, int p)
    {
        while(x <= n)
        {
            f[x] += p; 
            x += lowbit(x);
        }
    }
    
    int sum(int x)
    {
        int res = 0;
        while(x)
        {
            res += f[x];
            x -= lowbit(x);
        }
        return res;
    }
    
    int query(int l, int r) { return sum(r) - sum(l - 1); }
}S;
 
void read(int& x)
{
    int f = 1; x = 0; char ch = getchar();
    while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
    while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
    x *= f;
}
 
void AddEdge(int to, int from)
{
    e[num] = Edge{to, head[from]};
    head[from] = num++;
}
 
void dfs(int u, int fa)
{
    L[u] = ++id;
    for(int i = head[u]; ~i; i = e[i].next)
    {
        int v = e[i].to;
        if(v == fa) continue;
        dfs(v, u);
    }
    R[u] = id;
}
 
int main()
{
    memset(head, -1, sizeof(head)); num = 0;
    read(n);
    REP(i, 1, n)
    {
        int u, v; read(u), read(v);
        AddEdge(u, v); AddEdge(v, u); 
    }
    _for(i, 1, n) 
    {
        s[i] = 1;
        S.add(i, 1);
    }
    
    dfs(1, -1);
    read(m);
    
    while(m--)
    {
        char op[5]; int x;
        scanf("%s", op); read(x);
        if(op[0] == 'Q') printf("%d
", S.query(L[x], R[x]));
        else
        {
            int id = L[x];
            if(s[id]) S.add(id, -1);
            else S.add(id, 1);
            s[id] = !s[id];
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/sugewud/p/9819296.html