Wannafly Camp 2020 Day 1E 树与路径 - 树上差分,LCA
Wannafly Camp 2020 Day 1E 树与路径 - 树上差分,LCA
Wannafly Camp 2020 Day 1E 树与路径 - 树上差分,LCA

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1000005;

vector <int> g[N];
int f[N],dis[N],fa[N][20],vis[N],n,m,t1,t2,t3,t4,ps[N],pt[N],lc[N],ans;
int a[N],d[N];

void dfs1(int p) {
	vis[p] = 1;
	for (int i = 0; i < g[p].size(); i++)
		if (!vis[g[p][i]])
			fa[g[p][i]][0] = p,
			dis[g[p][i]] = dis[p] + 1,
			dfs1(g[p][i]);
}

int lca(int p, int q) {
	if (dis[p] < dis[q]) swap(p, q);
	for (int i = 18; i >= 0; --i)
		if (dis[fa[p][i]] >= dis[q])
			p = fa[p][i];
	for (int i = 18; i >= 0; --i)
		if (fa[p][i] - fa[q][i]) p = fa[p][i], q = fa[q][i];
	if (p - q) p = fa[p][0], q = fa[q][0];
	return p;
}

void dfs2(int p) {
    vis[p] = 1;
    for(int i=0;i<g[p].size();i++) {
        int q=g[p][i];
        if(vis[q]) continue;
        dfs2(q);
        a[p] += a[q] + d[q];
        d[p] += d[q];
    }
}

void dfs3(int p) {
    vis[p]=1;
    for(int i=0;i<g[p].size();i++) {
        int q=g[p][i];
        if(vis[q]) continue;
        a[q] += a[p];
        dfs3(q);
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<n;i++) {
        cin>>t1>>t2;
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    dis[1]=1;
    dfs1(1);
    for (int j = 1; j <= 18; j++)
		for (int i = 1; i <= n; i++)
			fa[i][j] = fa[fa[i][j - 1]][j - 1];
    for(int i=1;i<=m;i++) {
        cin>>ps[i]>>pt[i];
        lc[i]=lca(ps[i],pt[i]);
        ans+=(dis[ps[i]]-dis[lc[i]])*(dis[pt[i]]-dis[lc[i]]);
        int l = (dis[ps[i]]-dis[lc[i]])+(dis[pt[i]]-dis[lc[i]]);
        int s = (dis[ps[i]]-dis[lc[i]]), u = ps[i];
        a[u] += 1-l; d[u] += 2; a[lc[i]] -= 1-l+2*s; d[lc[i]] -= 2;
        s = (dis[pt[i]]-dis[lc[i]]); u = pt[i];
        a[u] += 1-l; d[u] += 2; a[lc[i]] -= 1-l+2*s; d[lc[i]] -= 2;
    }
    //for(int i=1;i<=n;i++) cout<<a[i]<<" "<<d[i]<<endl;
    memset(vis,0,sizeof vis);
    dfs2(1);
    memset(vis,0,sizeof vis);
    dfs3(1);
    for(int i=1;i<=n;i++) cout<<ans-a[1]+a[i]<<endl;
}

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-09-25
  • 2021-06-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-03
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案