zoukankan      html  css  js  c++  java
  • 2020 CCPC-Wannfaly-da1 树与路径

    回想Day1真是可怕,场场都是倒数的。。。。(金牌爷太强了)

    题目如下(吉老师出的题)

    传送门:https://ac.nowcoder.com/acm/contest/3979/E

     个人感觉这题不是很难那种(不过比赛时候确实没写出来)因为确实没有练习过树上差分,不知道树上前缀和有什么用。。。

     公式就是这样了,吉老师写的更简便,(但是看不懂)

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5 + 100;
    ll dep[maxn];
    int f[maxn][30];
    ll dp[maxn];//答案
    ll list[maxn];//前缀
    ll cnt[maxn];
    ll ans[maxn];
    
    vector<int>G[maxn];
    void insert(int be, int en) {
    	G[be].push_back(en);
    }
    
    int dfs(int x, int fa) {
    	dep[x] = dep[fa] + 1;
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == fa) continue;
    		f[p][0] = x;
    		dfs(p, x);
    	}
    	return 0;
    }
    int LCA(int x, int y) {
    	if (dep[x] > dep[y]) swap(x, y);
    	for (int i = 22; i >= 0; i--) {
    		if (dep[x] <= dep[f[y][i]]) {
    			y = f[y][i];
    		}
    	}
    	if (x == y) return x;
    	for (int i = 22; i >= 0; i--) {
    		if (f[x][i] != f[y][i]) {
    			x = f[x][i];
    			y = f[y][i];
    		}
    	}
    	return f[x][0];
    }
    struct node {
    	int be, en;
    	ll len;
    }que[maxn];
    int dfs1(int x, int fa) {
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == fa) continue;
    		dfs1(p, x);
    		ans[x] += ans[p];
    		cnt[x] += cnt[p];
    	}
    	list[x] = cnt[x];
    	return 0;
    }
    
    int dfs2(int x, int fa) {
    
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == fa) continue;
    		dfs2(p, x);
    		ans[x] += ans[p];
    		list[x] += list[p];
    	}
    	return 0;
    }
    
    int dfs3(int x, int fa) {
    
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == fa) continue;
    		dp[p] = dp[x] + 2 * list[p] - ans[p] - cnt[p];
    		dfs3(p, x);
    	}
    	return 0;
    }
    int main() {
    	int n, m;
    	int be, en;
    	scanf("%d %d", &n, &m);
    	for (int i = 1; i < n; i++) {
    		scanf("%d %d", &be, &en);
    		insert(be, en);
    		insert(en, be);
    	}
    	dfs(1, 0);
    	for (int k = 1; k < 25; k++) {
    		for (int i = 1; i <= n; i++) {
    			f[i][k] = f[f[i][k - 1]][k - 1];
    		}
    	}
    	ll cns = 0;
    	for (int i = 0; i < m; i++) {
    		scanf("%d %d", &be, &en);
    		int root = LCA(be, en);
    		cnt[be]++;
    		cnt[en]++;
    		cnt[root] -= 2;
    		ll d = dep[be] + dep[en] - 2 * dep[root];
    		que[i].be = be;
    		que[i].en = en;
    		que[i].len = d;
    		dp[1] += 1LL*(dep[be] - dep[root])*(dep[en] - dep[root]);
    	}
    	dfs1(1, -1);
    	ll len;
    	for (int i = 0; i < m; i++) {
    		be = que[i].be;
    		en = que[i].en;
    		len = que[i].len;
    		int root = LCA(be, en);
    		ans[be] += len;
    		ans[en] += len;
    		ans[root] -= 2 * len;
    		
    		list[root] -= (dep[be] - dep[root]);
    		list[root] -= (dep[en] - dep[root]);
    
    	}
    	dfs2(1, -1);
    	dfs3(1, -1);
    	for (int i = 1; i <= n; i++) {
    		printf("%lld
    ", dp[i]);
    	}
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    Z遮罩层完全覆盖页面
    页面加载完成时
    文字超出不换行,用省略号表示
    去掉最后一个元素的边线
    电话点击即可拨打
    制作对话的三角形
    active在iphone上不起作用
    jquery选择后代以及toggle,toggleClass用法
    button点击变换颜色时出现一个蓝色边框
    表格边框的实现
  • 原文地址:https://www.cnblogs.com/lesning/p/12217984.html
Copyright © 2011-2022 走看看