Dfs order Qauqaut of the game

Dfs order Qauqaut of the game

Two \ (n \) node of the tree, not the same, ask how many points \ ((u, v) \ ) in both trees are met path \ (v \) in \ (u \) subtree

\ (N \ 10 ^ 5 \)

violence:

\ (n ^ 2 \) violence enumerated by points \ (DFS \) sequence \ (O (1) \) determines a non-satisfied condition,Or Euler sequence \ (O (1) \) seeking lca

Correct answer:

Xianpao first tree, which obtains \ (DFS \) sequence, node record \ (I \) a \ (DFS \) sequence starting and ending position.

Then ran the second tree, maintaining a subscript \ (dfs \) Fenwick tree sequence, the first pass to each node \ (i \) , we count the current node in \ (dfs \) before the sequence ( is met on the first node tree \ (I \) in \ (J \) in the subtree), and in that the current has traversed a second tree node (i.e., a second tree node satisfies \ (I \) in \ (J \) subtree) number, added to the answer. This process is equivalent statistics for each \ ((u, v) \ ) in the \ (v \) .

Look at the specific code to achieve it.

#include <cstdio>
#define MAXN 100001
using namespace std;
inline int read(){
    char ch=getchar();int s=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') s=s*10+(ch^'0'), ch=getchar();
    return s;
}
int n;
int tre[MAXN];
void add(int x, int val){
    while(x<=n)
        tre[x]+=val,x+=x&(-x);
}
int get_sum(int x){
    int res=0;
    while(x>0)
        res+=tre[x],x-=x&(-x);
    return res;
}
int dfn[MAXN],dfn_out[MAXN],cnt;
int ans[MAXN];
namespace tre1 {
    int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
    inline void add_edge(int u, int v){
        vv[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    void dfs(int u, int fa){
        dfn[u]=++cnt;
        for(int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            if(v==fa) continue;
            dfs(v, u);
        }
        dfn_out[u]=cnt;
    }
}
namespace tre2 {
    int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
    inline void add_edge(int u, int v){
        vv[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    void solve(int u, int fa){
        ans[u]=get_sum(dfn[u]-1);
        add(dfn[u], 1);
        add(dfn_out[u], -1);
        for(int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            if(v==fa) continue;
            solve(v, u);
        }
        add(dfn[u], -1);
        add(dfn_out[u], 1);
    }
}
int main(){
    //freopen("climb.in", "r", stdin);
    //freopen("climb.out", "w", stdout);
    n=read();
    for(int i=1;i<n;++i){
        int u=read(),v=read();
        tre1::add_edge(u, v);
        tre1::add_edge(v, u);
    }
    for(int i=1;i<n;++i){
        int u=read(),v=read();
        tre2::add_edge(u, v);
        tre2::add_edge(v, u);
    }
    tre1::dfs(1, 1);
    tre2::solve(1, 1);
    long long sum=0;
    for(int i=1;i<=n;++i) sum+=ans[i];
    printf("%lld", sum);
    return 0;
}

Guess you like

Origin www.cnblogs.com/santiego/p/11777458.html