[概率][lca][dfs][树形dp] Jzoj P4225 宝藏

Description

 

Input

Output

 

Sample Input

2
3
1 0
1 2
2
1 0 1
2 0 2 1
4
0 1
2 0
3 0
1
3 0 1 0 1

Sample Output

1.0000
5.0000
<空行>
11.0000
 

Data Constraint

题解

  • 这题一看似成相识,就是这题树的小改
  • 具体做法之前的博客已经讲了很清楚了
  • 那么这题的话,就直接把其所有询问存下来,按顺序跑就好了
  • 对于它保留小数点后4位数,其实呢,这个东东就是个摆设,直接输出“.0000”就好了

代码

 1 #include <cstdio> 
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cmath>
 5 #define ll long long
 6 #define N 1000010
 7 using namespace std;
 8 const ll mo=1e9+7;
 9 struct edge {int to,from;}e[N*2];
10 int n,q,head[N],cnt,T,Q,a[1010],lca;
11 ll sum,f[N][21],dep[N],ans,k1[N],k2[N];
12 void insert(int x,int y) {e[++cnt].to=y; e[cnt].from=head[x]; head[x]=cnt;}
13 void dfs(int x,int fa)
14 {
15     f[x][0]=fa,dep[x]=dep[fa]+1,k1[x]=0;
16     for (int i=head[x];i;i=e[i].from)
17         if (e[i].to!=fa)
18             dfs(e[i].to,x),k1[x]=(k1[x]+k1[e[i].to]+1)%mo;
19     k1[x]=(k1[x]+1)%mo;
20 }
21 void dfs1(int x,int fa)
22 {
23     ll sum=0;
24     for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) sum=(sum+k1[e[i].to]+1)%mo;
25         else sum=(sum+k2[x]+1)%mo;
26     for (int i=head[x];i;i=e[i].from)
27         if (e[i].to!=fa)
28             k2[e[i].to]=((sum-k1[e[i].to])%mo+mo)%mo,dfs1(e[i].to,x);
29 }
30 void dfs2(int x,int fa)
31 {
32     k1[x]=(k1[x]+k1[fa])%mo,k2[x]=(k2[x]+k2[fa])%mo;
33     for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) dfs2(e[i].to,x);
34 }
35 int getlca(int u,int w)
36 {
37     if (dep[u]<dep[w]) swap(u,w);
38     int d=dep[u]-dep[w];
39     if (d) for (int i=0;i<=log(n)/log(2)+1&&d;i++,d>>=1) if (d&1) u=f[u][i];
40     if (u==w) return u;
41     for (int i=log(n)/log(2)+1;i>=0;i--) if (f[u][i]!=f[w][i]) u=f[u][i],w=f[w][i];
42     return f[u][0];
43 }
44 int main()
45 {
46     scanf("%d",&T);
47     while (T--)
48     {    
49         scanf("%d",&n),memset(head,0,sizeof(head)),memset(k1,0,sizeof(k1)),memset(k2,0,sizeof(k2)),memset(f,0,sizeof(f)),memset(dep,0,sizeof(dep));
50         for (int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),insert(u,v),insert(v,u);
51         dfs(1,-1),k1[1]=k2[1]=0,dfs1(1,-1),dfs2(1,-1);
52         for (int i=1;i<=log(n)/log(2)+1;i++) for (int j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1];
53         scanf("%d",&Q);
54         while (Q--)
55         {
56             scanf("%d",&q),ans=0;
57             for (int i=1;i<=q+1;i++) scanf("%d",&a[i]);
58             for (int i=1;i<=q;i++)
59                 lca=getlca(a[i],a[i+1]),
60                 (ans+=(k1[a[i]]-k1[lca]+k2[a[i+1]]-k2[lca]+mo)%mo)%=mo;
61             printf("%.4lf\n",(double)ans);
62         }
63         printf("\n");
64     }
65 }

猜你喜欢

转载自www.cnblogs.com/Comfortable/p/10323712.html
今日推荐