This idea is very good question.
$ K $ we can point out, it is required to $ k $ points are divided into not more than $ m $ program number set.
Order $ f [i] [j] $ represents the front dividing $ $ I $ points to the program number of sets J $.
Then there is $ f [i] [j] = f [i-1] [j-1] + f [i-1] [j] * (j-fail [i]) $, where $ fail [i] $ $ I $ representative of the number of ancestors of this path root.
And $ fail [i] $ embodiment are solved: Virtual statistics / management path tree data structure and, where selected LCT used to maintain.
code:
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #define N 100007 #define ll long long #define mod 1000000007 #define setIO(s) freopen(s".in","r",stdin) using namespace std; namespace LCT { #define lson t[x].ch[0] #define rson t[x].ch[1] struct node { int ch[2],f,rev,sum,val; }t[N]; you sta [N]; int get(int x) { return t[t[x].f].ch[1]==x; } int isrt(int x) { return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); } void pushup(int x) { t[x].sum=t[lson].sum+t[rson].sum+t[x].val; } void mark(int x) { t[x].rev^=1; swap(lson,rson); } void pushdown(int x) { if(t[x].rev) { if(lson) mark(lson); if(rson) mark(rson); t[x].rev=0; } } void rotate(int x) { int old=t[x].f,fold=t[old].f,which=get(x); if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old; t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; pushup(old),pushup(x); } void splay(int x) { int v = 0, u = x ago; for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f; for (; v; - v) pushdown (sta [v]); for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) { if(t[fa].f!=u) rotate(get(fa)==get(x)?fa:x); } } void Access(int x) { for(int y=0;x;y=x,x=t[x].f) { splay(x); rson = y; pushup(x); } } Void makeroot (int x) { Access(x),splay(x),mark(x); } void split(int x,int y) { makeroot (x), Access (y), splay (y); } void add(int x,int v) { Access(x),splay(x); t[x].val+=v,pushup(x); } int query(int x) { Access(x),splay(x); return t[x].sum; } #undef lson #undef rson }; int n,edges; int hd[N],to[N<<1],nex[N<<1],f[N],A[N],dp[N][302]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u,int ff) { LCT::t[u].f=ff; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs (v, u); } } int main () { // setIO("input"); int i,j,q; scanf("%d%d",&n,&q); for(i=1;i<n;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs(1,0); for(i=1;i<=q;++i) { int k,m,r,flag=0; scanf("%d%d%d",&k,&m,&r); LCT :: makeroot (r); for(j=1;j<=k;++j) { scanf("%d",&A[j]); LCT::add(A[j],1); } for(j=1;j<=k;++j) { f[j]=LCT::query(A[j])-1; if(f[j]>m) flag=1; } for(j=1;j<=k;++j) LCT::add(A[j],-1); if(flag) printf("0\n"); else { sort(f+1,f+1+k); dp[1][1]=1; for(j=2;j<=k;++j) { for(int p=1;p<=min(j,m);++p) { dp[j][p]=0; if(p<f[j]) dp[j][p]=dp[j-1][p-1]; else dp[j][p]=(ll)(dp[j-1][p-1]+1ll*(p-f[j])*dp[j-1][p]%mod)%mod; } } int years = 0; for(j=1;j<=m;++j) ans=(ans+dp[k][j])%mod; printf("%d\n",ans); } } return 0; }