首页 > 其他 > 详细

bzoj1103

时间:2017-07-26 15:21:44      阅读:297      评论:0      收藏:0      [点我收藏+]

dfs序

dfs序真神奇

dfs求出入栈时刻和出栈时刻,然后在in和out分别打上1和-1就能统计路径和了。

其实这里dfs序能够让我们求一个点处于哪些节点的子树内,而一个节点只处于从自己到跟路径的节点的。

这里的dfs序有些像括号序列,如果一个点不在另一个点的子树内,那么也就不在另一个点的括号内,那么另一个点的括号也闭合了,+1-1抵消

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N = 250010;
int n, m, top, cnt;
int st[N], in[N], out[N];
vector<int> G[N];
struct BIT {
    int tree[N << 1];
    int lowbit(int i)
    {
        return i & (-i);
    }
    void update(int pos, int delta)
    {
        for(int i = pos; i <= n * 2 + 1; i += lowbit(i)) tree[i] += delta;
    }
    int query(int pos)
    {
        int ret = 0;
        for(int i = pos; i; i -= lowbit(i)) ret += tree[i];
        return ret;
    }
} t;
void dfs(int u, int last)
{
    in[u] = ++cnt;
    for(int i = 0; i < G[u].size(); ++i)
    {
        int v = G[u][i];
        if(v == last) continue;
        dfs(v, u);
    }
    out[u] = ++cnt;
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i < n; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1, 0);
    scanf("%d", &m);
    for(int i = 2; i <= n; ++i)
    {
        t.update(in[i], 1);
        t.update(out[i], -1);
    }
    for(int i = 1; i < n + m; ++i)
    {
        char opt[10];
        int u, v;
        scanf("%s", opt);
        if(opt[0] == A)
        {
            scanf("%d%d", &u, &v);
            t.update(in[v], -1);
            t.update(out[v], 1);
        }
        if(opt[0] == W)
        {
            scanf("%d", &u);
            printf("%d\n", t.query(in[u]));
        }
    }
    return 0;
}
View Code

 

bzoj1103

原文:http://www.cnblogs.com/19992147orz/p/7239667.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!