题解
操作倒着来,则当前操作不会影响之后的操作,
对于每次操作更新答案 ans[ui]=ans[vi]=ans[ui]+ans[vi]-(ans[ui] 并 ans[vi])
对于二者并集,即是上一次合并时的ans (ps:上一次二者合并,ans相同即为这次操作的并集),记录一下即可
#include <cstdio> #define RE register #define FOR(i,a,b) for(RE int i=a;i<=b;++i) #define ROF(i,a,b) for(RE int i=a;i>=b;--i) #define sc(n) scanf("%d",&n) using namespace std; const int maxn=5e5+10; int n,m,a[maxn],b[maxn],c[maxn],t[maxn],ans[maxn]; int main() { sc(n),sc(m);ans[n]=1; FOR(i,1,n-1)sc(a[i]),sc(b[i]),ans[i]=1; FOR(i,1,m)sc(c[i]); ROF(i,m,1)ans[a[c[i]]]=ans[b[c[i]]]=t[c[i]]=ans[a[c[i]]]+ans[b[c[i]]]-t[c[i]]; FOR(i,1,n-1)printf("%d ", ans[i]);printf("%d",ans[n]); return 0; }