zoukankan      html  css  js  c++  java
  • [JZOJ 5814] 树

    题目:从u到v经过多少条边。
    思路:
    考虑他是怎么走的??
    \(u\)\(v\)一定是\(fa[u]\),\(fa[fa[u]]\),反正就是走\(LCA\),那么如果算出每个点到父亲的期望步数,和父亲到该点的期望步数就可做了。
    \(f(x) : x -> fa,g(x) : fa -> x\).

    那么:
    \(f(x) = {1 \over deg[x]} + \sum_{y是x的儿子} {{f(y) + 1 + f(x)} \over deg[x]}\)

    \(g(x) = {1 \over deg[fa[x]]} + {{1 + g[x] + g[fa[x]]} \over deg[fa[x]]} + \sum_{y 属于 son[fa[x]]{xor}y != x} {{g[x] + 1 + f[x]} \over {deg[fa[x]]}}\)
    于是我们罪恶的\(LCA\)开始了(情报中心)

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    inline int read () {
    	int q=0,f=1;char ch = getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')f=-1;ch=getchar();
    	}
    	while(isdigit(ch)){
    		q=q*10+ch-'0';ch=getchar();
    	}
    	return q*f;
    }
    const int maxn = 1000010;
    ll dp[maxn][2];
    int head[maxn];
    int cnt;
    int siz[maxn];
    int f[maxn][20];
    int dep[maxn];
    int n,m,u,v,x,y;
    struct node {
    	int to;
    	int nxt;
    }e[maxn << 1];
    const int mod = 1e9+7;
    inline void add(int u,int v) {
    	e[++cnt].to = v;
    	e[cnt].nxt = head[u];
    	head[u] = cnt;
    	return;
    }
    inline void Add_edge(int u,int v) {
    	add(u,v);add(v,u);
    	return;
    }
    inline void dfs1(int x,int fa) {
    	siz[x] = 1;
    	for(int i = head[x];i;i=e[i].nxt) {
    		int y = e[i].to;
    		if(y != fa) {
    			dfs1(y,x);
    			siz[x] += siz[y];
    		}
    		dp[x][0] = siz[x] * 2 - 1;
    		dp[x][1] = (n - siz[x]) * 2 - 1;
    	}
    }
    inline void dfs2(int x,int fa) {
    	dep[x] = dep[fa] + 1;
    	dp[x][0] += dp[fa][0];
    	dp[x][1] += dp[fa][1];
    	f[x][0] = fa;
    	for(int i = 1;i <= 17; ++i) {
    		f[x][i] = f[f[x][i - 1]][i - 1];
    	}
    	for(int i = head[x];i;i=e[i].nxt) {
    		int y = e[i].to;
    		if(y != fa) dfs2(y,x);
    	}
    }
    inline int lca(int x,int y) {
    	if(dep[x] < dep[y]) swap(x,y);
    	for(int i = 17;i >= 0; --i) {
    		if(dep[x] - (1 << i) >= dep[y]) {
    			x = f[x][i];
    		}
    	}
    	if(x == y) return x;
    	for(int i = 17;i >= 0; --i) {
    		if(f[x][i] == f[y][i]) {
    			continue;
    		}
    		x = f[x][i];
    		y = f[y][i];
    	}
    	return f[x][0];
    }
    int main () {
    	freopen("tree.in","r",stdin);
    	freopen("tree.out","w",stdout);
    	n = read(),m = read();
    	for(int i = 1;i < n; ++i) {
    		u = read(),v = read();
    		Add_edge(u,v);
    	}
    	dfs1(1,0);
    	dp[1][0] = dp[1][1] = 0;
    	dfs2(1,0);
    	for(int i = 1;i <= m; ++i) {
    		x = read(),y = read();
    		int anc = lca(x,y);
    		printf("%d\n",(dp[x][0] + dp[y][1] - dp[anc][0] - dp[anc][1])%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Windows下Subversion配置管理员指南
    asp.net HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
    SQL Server 2000不能远程连接的问题
    ASP通用分页类[强]
    不错的站长工具网址(不断收集中....)
    函数的四种调用模式
    HDOJ 3943 Kth Nya Number(数位DP)
    HDOJ 2196 Computer
    HDOJ 3695 Computer Virus on Planet Pandora (AC自动机)
    HDOJ 4277 USACO ORZ (搜索+剪枝)
  • 原文地址:https://www.cnblogs.com/akoasm/p/9579158.html
Copyright © 2011-2022 走看看