Codeforces 191C (LCA+树上差分算法)

xiaoxiao2021-02-28  51

题面

传送门 题目大意: 给出一棵树,再给出k条树上的简单路径,求每条边被不同的路径覆盖了多少次

分析

解决这个问题的经典做法是树上差分算法 它的思想是把”区间”修改转化为左右端点的修改 在树上,每个节点初始权值为0,对于每条路径(x,y),我们令节点x的权值+1,节点y的权值-1,节点LCA(x,y)的权值-2 最后进行一次DFS,求出F[x]表示x为根的子树中各节点的权值之和,F[x]就是x与它的父节点之间的树边被覆盖的次数 用dfs序+ST表求LCA,时间复杂度 O(nlog2n+k) O ( n l o g 2 n + k )

代码

#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define maxn 100005 #define maxlog 32 using namespace std; int n,k; struct edge{ int from; int to; int next; int index; }E[maxn*2]; int head[maxn]; int size=0; void add_edge(int u,int v,int id){ size++; E[size].from=u; E[size].to=v; E[size].next=head[u]; E[size].index=id; head[u]=size; } int dfn[maxn*2]; int used[maxn]; int fipos[maxn*2]; int deep[maxn*2]; int st[maxn*4][maxlog]; int cnt=0; void get_dfn(int u,int d){ dfn[++cnt]=u; if(fipos[u]==0){ fipos[u]=cnt; deep[u]=cnt; } used[u]=1; for(int i=head[u];i;i=E[i].next){ if(!used[E[i].to]){ get_dfn(E[i].to,d+1); dfn[++cnt]=u; } } } void st_init(){ for(int i=1;i<=(n-1)*2;i++){ st[i][0]=dfn[i]; } for(int j=1;(1<<j)<=(n-1)*2;j++){ for(int i=1;i<=(n-1)*2;i++){ if(deep[st[i][j-1]]<deep[st[i+(1<<(j-1))][j-1]]) st[i][j]=st[i][j-1]; else st[i][j]=st[i+(1<<(j-1))][j-1]; } } } int st_query(int l,int r){ if(l>r) swap(l,r); int k=log2(r-l+1); if(deep[st[l][k]]<deep[st[r-(1<<k)+1][k]]) return st[l][k]; else return st[r-(1<<k)+1][k]; } int lca(int x,int y){ int fx=fipos[x]; int fy=fipos[y]; return st_query(fx,fy); } int len[maxn]; int outlen[maxn];//按题目顺序输出 void get_len(int u){ used[u]=1; for(int i=head[u];i;i=E[i].next){ if(!used[E[i].to]){ get_len(E[i].to); len[u]+=len[E[i].to]; outlen[E[i].index]+=len[E[i].to]; } } } int main(){ int u,v; scanf("%d",&n); for(int i=1;i<=n-1;i++){ scanf("%d %d",&u,&v); add_edge(u,v,i); add_edge(v,u,i); } get_dfn(1,0); st_init(); scanf("%d",&k); for(int i=1;i<=k;i++){ scanf("%d %d",&u,&v); //树上差分算法 len[u]++; len[v]++; len[lca(u,v)]-=2; } memset(used,0,sizeof(used)); get_len(1); for(int i=1;i<=n-1;i++) printf("%d ",outlen[i]); }
转载请注明原文地址: https://www.6miu.com/read-2614010.html

最新回复(0)