hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)

题意:

N个点形成一棵树。给出根结点P还有树结构的信息。

输出每个点的F[i]。F[i]:以i为根的所有子结点中编号比i小的数的个数。

0<n<=10^5

思路:

方法一:直接DFS,进入结点x时记录一下比x小的数的个数。出来x时记录一下比x小的数的个数。相减就是F[x]。结合树状数组。

方法二:写下DFS序。对DFS序列建线段树。然后从小到大对结点进行插入。用线段树统计。

代码:(方法一)

int const N=1e5+5;

int n,p;
vector<int> G[N];
int C[N];
int ans[N];
stack<int> S;
bool vis[N];

void Add(int x){
    for(int i=x;i<=n;i+=lowbit(i)){
        C[i]++;
    }
}
int query(int x){
    int ret=0;
    for(int i=x;i>0;i-=lowbit(i)){
        ret+=C[i];
    }
    return ret;
}

void dfs(int u){
    while(!S.empty()){
        S.pop();
    }
    mem(vis,false);
    S.push(u);
    vis[u]=true;
    while(!S.empty()){
        int now=S.top();
        int L=G[now].size();
        bool flag=false;
        rep(i,0,L-1){
            if(vis[G[now][i]]==false){
                vis[G[now][i]]=true;
                flag=true;
                int t=G[now][i];
                ans[t]=query(t-1);
                S.push(G[now][i]);
                break;
            }
        }
        if(!flag){
            ans[now]=query(now-1)-ans[now];
            Add(now);
            S.pop();
        }
    }
}

int main(){

    while(scanf("%d%d",&n,&p)!=EOF,n||p){

        rep(i,1,n) G[i].clear();
        mem(C,0);
        mem(ans,0);

        rep(i,1,n-1){
            int a,b;
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        dfs(p);
        rep(i,1,n-1) printf("%d ",ans[i]); cout<<ans[n]<<endl;
    }

    return 0;
}
时间: 2024-08-08 17:11:19

hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)的相关文章

hdu 3887 Counting Offspring dfs序+树状数组

Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description You are given a tree, it’s root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose numbe

HDU 3887 Counting Offspring(DFS序求子树权值和)

Problem Description You are given a tree, it's root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose number is less than i in all the succeeding nodes of node i. Now we need to calculate f(i) for any possible i

Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问vj, kj 你需要回答在以vj为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少为kj. (莫队居然可以过) 首先转DFS序,这样就变成了区间查询. 然后直接套用莫队,求出每次询问状态下的t[],t[k]表示当前区间内拥有k个节点的颜色数量. 然后统计t[k] + t[k + 1], ..., t[MAX]即可,这个过程用树状数组维护. #include <bits/stdc++.h>

【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim

考虑树状数组区间修改(只对其子树的答案有影响)点查询,每个点记录的是它到根路径上的权值异或和. 答案时query(L)^query(R)^a[lca]. 这种方法在支持区间加法.减法的树上询问的时候可以避免树链剖分. 可能爆栈,考虑手动开栈.(诶诶Tarjan预处理lca的时候怎么没手动开栈?不要在意^_^) 实际上不会爆的. #include<cstdio> #include<stack> #include<algorithm> #include<queue&g

【dfs序】【树状数组】bzoj1103 [POI2007]大都市meg

预处理出每个点到根节点的土路数,插到一个树状数组里,然后每次修改只会对子树中的节点造成影响,于是相当于区间修改.点查询了. #include<cstdio> using namespace std; #define N 250001 int n,en,v[N<<1],next[N<<1],first[N],m; void AddEdge(const int &U,const int &V) { v[++en]=V; next[en]=first[U];

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)

Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8984    Accepted Submission(s): 4594 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球

HDU 3333 Turing Tree (离散化+离线处理+树状数组)

Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick t

HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)

思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了.线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料 线段树AC代码: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define N 50005 int num