• CF519E


    [LCA到x和LCA到y的距离相等且x,y不是同一个点\ ans=n-siz[x]-siz[y]\ LCA到x和LCA到y的距离不相等,且分别为a,b\ (1)a+b为奇数,a-b一定为奇数\ (2)a+b偶数,令a>b,a上必有一点的LCA-(a-b)/2到x,y距离相等\ 设这个点为P,以P为根的子树结点-P到x的结点数+1=到x,y距离相等的点数\ x=y时ans=n ]

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N = 1e5 + 5;
    int n,m,fa[N][20],dep[N],siz[N];
    struct edge{int to,next;}e[N<<1]; int head[N],tot;
    inline void add(int u,int v){e[++tot] = (edge){v,head[u]}; head[u] = tot;}
    void dfs(int x,int f){
    	fa[x][0] = f; siz[x] = 1;
    	for(int i = 1;i < 20;++i) fa[x][i] = fa[fa[x][i-1]][i-1];
    	dep[x] = dep[f] + 1;
    	for(int i = head[x];i;i = e[i].next){
    		int v = e[i].to;
    		if(v == f) continue;
    		dfs(v,x); siz[x] += siz[v];
    	}
    }
    int LCA(int u,int v) {
        if(dep[u]>dep[v]) 
    		swap(u,v);
        
        for(int i=19;i>=0;i--)
            if(dep[fa[v][i]] >= dep[u])  v = fa[v][i];
    
        if(u==v) 
    		return u;
        for(int i=19;i>=0;i--) {
            if(fa[u][i]==fa[v][i]) 
    			continue;
            u = fa[u][i];
            v = fa[v][i];
        }
        return fa[u][0];
    }
    int jump_up(int u,int k) {
        int i = 0;
        while(k) {
            if(k&1) u = fa[u][i];
            k>>=1;
            i++;
        }
        return u;
    }
    inline int read(){
    	int x = 0;char c = getchar();
    	while(!isdigit(c))c = getchar();
    	while(isdigit(c))x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    	return x;
    }
    int main(){
    	n = read(); int x,y;
    	for(int i = 1;i < n;++i){
    		x = read(); y = read();
    		add(x,y); add(y,x);
    	}
    	m = read(); dfs(1,0);
    	for(int i = 1;i <= m;++i){
    		x = read(); y = read();
    		int lca = LCA(x,y);
    		if(x == y) printf("%d
    ",n);
    		else if(dep[x] == dep[y]){
    			int a =jump_up(x,dep[x]-dep[lca]-1);
                int b = jump_up(y,dep[y]-dep[lca]-1);
                printf("%d
    ",n - siz[a] - siz[b]);
    		}
    		else{
    			 int d = dep[x]+dep[y] -2*dep[lca];
                if(d & 1) puts("0");
                else {
                    if(dep[x]>dep[y]) swap(x,y);
                    int b = jump_up(y,d/2-1);
                    int a = fa[b][0];
                    printf("%d
    ",siz[a] - siz[b]);
    		}
    	}
    }
    }
    
  • 相关阅读:
    P1726 上白泽慧音
    P1993 小k的农场
    P1983 车站分级
    P1525 关押罪犯【二分+二分图】
    P1268 树的重量【构造】
    P1113 杂务
    F.Three pahs on a tree
    P1522 牛的旅行
    两个约束下的dp问题
    dp 最大正方形
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13647788.html
Copyright © 2020-2023  润新知