description
analysis
-
倍增+++期望
-
题解鲜有地写的很清晰……
-
大概就这样了吧……
-
然后对于求出来的fff值什么的,用倍增维护
-
每次询问其实就是用倍增在树上跳来跳去,这个实现很简单
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define MAXP 505
#define MAXN 50005
#define MAXM MAXN*2
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i])
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll anc[MAXN][17],dis1[MAXN][17],dis2[MAXN][17];
ll last[MAXM],next[MAXM],tov[MAXM];
ll f1[MAXN],f2[MAXN],d[MAXN],depth[MAXN],v[MAXP];
ll n,p,q,ans,tot,test;
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline ll max(ll x,ll y)
{
return x>y?x:y;
}
O3 inline void link(ll x,ll y)
{
next[++tot]=last[x],last[x]=tot,tov[tot]=y;
}
O3 inline void dfs1(ll x,ll y)
{
rep(i,x)if (tov[i]!=y)
{
anc[tov[i]][0]=x;
depth[tov[i]]=depth[x]+1;
}
f1[x]=d[x];
rep(i,x)if (tov[i]!=y)f1[x]+=f1[tov[i]];
f2[x]=max(0,2*(n-1)-f1[x]);
}
O3 inline void dfs2(ll x,ll y)
{
rep(i,x)if (tov[i]!=y)
{
dis1[tov[i]][0]=f1[tov[i]];
dis2[tov[i]][0]=f2[tov[i]];
dfs2(tov[i],x);
}
}
O3 inline ll lca(ll x,ll y)
{
if (depth[x]<depth[y])swap(x,y);
fd(i,16,0)if (depth[anc[x][i]]>depth[y])x=anc[x][i];
if (depth[x]!=depth[y])x=anc[x][0];
fd(i,16,0)if (anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
return x==y?x:anc[x][0];
}
O3 int main()
{
//freopen("T3.in","r",stdin);
test=read();
while (test--)
{
tot=0;
memset(d,0,sizeof(d));
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
memset(last,0,sizeof(last));
memset(next,0,sizeof(next));
memset(tov,0,sizeof(tov));
memset(anc,0,sizeof(anc));
memset(dis1,0,sizeof(dis1));
memset(dis2,0,sizeof(dis2));
n=read();
fo(i,1,n-1)
{
ll x=read()+1,y=read()+1;
link(x,y),link(y,x),++d[x],++d[y];
}
depth[1]=1,dfs1(1,0),dfs2(1,0);
fo(j,1,floor(log2(n)))fo(i,1,n)
{
anc[i][j]=anc[anc[i][j-1]][j-1];
dis1[i][j]=dis1[i][j-1]+dis1[anc[i][j-1]][j-1];
dis2[i][j]=dis2[i][j-1]+dis2[anc[i][j-1]][j-1];
}
q=read();
while (q--)
{
p=read(),ans=0;
fo(i,0,p)v[i]=read()+1;
fo(i,1,p)
{
ll x=v[i-1],y=v[i],LCA=lca(x,y);
if (LCA!=x)fd(i,16,0)if (depth[anc[x][i]]>=depth[LCA])ans+=dis1[x][i],x=anc[x][i];
if (LCA!=y)fd(i,16,0)if (depth[anc[y][i]]>=depth[LCA])ans+=dis2[y][i],y=anc[y][i];
}
printf("%lld.0000\n",ans);
}
printf("\n");
}
return 0;
}