题解: q次查询每次查询k个点 k的总和不超过1e5 那就->虚树 这个题分为两部分 前面先对每次查询的点建虚树 其次计数 对于新树上的每个关键点(查询点) 他能影响的m的范围 必然大于以r为根的祖先节点的个数 然后我们单独考虑每个节点的贡献为 当前集合个数减去其祖先节点的个数 然后我们考虑把每个点按照dfs序的下标考虑贡献 转移分为两部分
1.当前元素加入直接构成一个新集合
2,当前元素加入可以加入到 m(当前集合个数)-祖先节点个数
#include <bits/stdc++.h>
#define ll long long
#define inc(i,l,r) for(int i=l;i<=r;i++)
const int MAXN=3e5+10;
using namespace std;
const ll inf=1e18;
const ll MOD=1e9+7;
vector<int>vec[MAXN];
int f[MAXN][21];int dep[MAXN];
int st[MAXN],tot;
int p[MAXN],cnt1;
vector<int>V;
bool vis[MAXN];
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
ll Add(ll a, ll b){a+=b;if(a>=MOD)a-=MOD; return a;}
ll Mult(ll a, ll b){return (a*b)%MOD;}
void dfs(int v,int pre,int deep){
dep[v]=deep;f[v][0]=pre;p[v]=++cnt1;
for(int i=0;i<vec[v].size();i++){
int u=vec[v][i];
if(u!=pre){
dfs(u,v,deep+1);
}
}
}
void dfs1(int v){
inc(i,1,20)f[v][i]=f[f[v][i-1]][i-1];
for(int i=0;i<vec[v].size();i++){
int u=vec[v][i];
if(u!=f[v][0])dfs1(u);
}
}
int Lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
int tmp=dep[u]-dep[v];
for(int i=0;i<=20;i++)if(tmp&(1<<i))u=f[u][i];
if(u==v)return u;
for(int i=20;i>=0;i--){
if(f[u][i]!=f[v][i]){
u=f[u][i];
v=f[v][i];
}
}
return f[u][0];
}
ll dp[2][305];
void built(int x){
V.push_back(x);
if(!tot){st[++tot]=x;return ;}
int lca=Lca(x,st[tot]);
while(tot>1&&dep[lca]<dep[st[tot-1]]){
vec[st[tot]].push_back(st[tot-1]);
vec[st[tot-1]].push_back(st[tot]);
tot--;
}
if(dep[st[tot]]>dep[lca]){
vec[st[tot]].push_back(lca);
vec[lca].push_back(st[tot]);
tot--;
V.push_back(lca);
}
if(!tot||dep[lca]>dep[st[tot]])st[++tot]=lca;
st[++tot]=x;
}
int M[MAXN],St[MAXN],cnt;
void dfs2(int x,int pre,int deep){
if(vis[x])M[x]=deep+1,St[++cnt]=x;
for(int i=0;i<vec[x].size();i++){
if(vec[x][i]!=pre){
if(vis[x])dfs2(vec[x][i],x,deep+1);
else dfs2(vec[x][i],x,deep);
}
}
}
int n,m;
bool cmp(int aa,int bb){return p[aa]<p[bb];}
int main(){
n=read();m=read();
int u,v;
for(int i=1;i<n;i++)u=read(),v=read(),vec[u].push_back(v),vec[v].push_back(u);
dfs(1,0,0);dfs1(1);int k,q,r;
for(int i=1;i<=n;i++)vec[i].clear();
while(m--){
k=read();q=read();r=read();
tot=0;
V.push_back(r);
for(int i=1;i<=k;i++)v=read(),V.push_back(v),vis[v]=1;
sort(V.begin(),V.end(),cmp);
int sz=unique(V.begin(),V.end())-V.begin();
for(int i=1;i<=sz;i++)built(V[i-1]);
while(tot>1){vec[st[tot]].push_back(st[tot-1]),vec[st[tot-1]].push_back(st[tot]);tot--;}
cnt=0;dfs2(r,0,0);
int K=0;
inc(i,1,q)dp[K][i]=0;
dp[K][0]=1;
for(int i=1;i<=cnt;i++){
K=1-K;
inc(j,0,q)dp[K][j]=0;
for(int j=0;j<=q;j++){
if(j<q)dp[K][j+1]=Add(dp[K][j+1],dp[!K][j]);
if(M[St[i]]<=j)dp[K][j]=Add(dp[K][j],Mult(dp[!K][j],j-M[St[i]]+1));
}
}
ll ans=0;
inc(i,1,q)ans=Add(ans,dp[K][i]);
printf("%lld\n",ans);
for(int i=0;i<V.size();i++)vec[V[i]].clear(),vis[V[i]]=0;
V.clear();
}
return 0;
}