题面

不好讲,直接上式子吧=。=

设$dp[i][j]$表示考虑完$i$的子树后$i$的排名为$j$的方案数,然后转移类似树形背包,具体来说是(这里假设子树在$i$后选,其实反过来还用这个式子答案也是一样的,因为全反了)

$ans+=dp[nde][k]*dp[g][min(j-k,siz[g])]*C_{j-1}^{k-1}*C_{siz[nde]+siz[g]-j}^{siz[nde]-k}$

其中$j$是枚举的当前点加入$i$这个子树之后$i$前面总共有几个数,$k$是枚举的当前点加入这个子树之后$i$前面还有几个原来是$i$的,$g$是子树,解释一下

前两个是已有的信息,不解释了,$C_{j-1}^{k-1}$表示$i$已经有的这$k$个点随便排(原有顺序还要保持不变,所以是C),后面那个$C_{siz[nde]+siz[g]-j}^{siz[nde]-k}$同理

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,mod=1e9+;
int fac[N],inv[N],siz[N],f[N][N];
int p[N],noww[*N],goal[*N],val[*N];
int T,n,t1,t2,cnt; char rd[];
void Link(int f,int t,int v)
{
noww[++cnt]=p[f],p[f]=cnt;
goal[cnt]=t,val[cnt]=v;
}
int Qpow(int x,int k)
{
if(k==) return x;
int tmp=Qpow(x,k/);
return k%?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
}
int C(int a,int b)
{
if(a<b) return ;
return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
}
void Prework()
{
fac[]=inv[]=;
for(int i=;i<=;i++)
fac[i]=1ll*fac[i-]*i%mod;
inv[]=Qpow(fac[],mod-);
for(int i=;i;i--)
inv[i]=1ll*inv[i+]*(i+)%mod;
scanf("%d",&T);
}
void Init()
{
memset(p,,sizeof p);
memset(f,,sizeof f);
cnt=,scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%s%d",&t1,rd,&t2),t1++,t2++;
Link(t1,t2,rd[]=='<'),Link(t2,t1,rd[]=='>');
}
for(int i=;i<=n;i++) f[i][]=;
}
void DFS(int nde,int fth)
{
siz[nde]=;
for(int i=p[nde];i;i=noww[i])
{
int g=goal[i];
if(g!=fth)
{
DFS(g,nde);
if(val[i])
{
for(int j=siz[nde]+siz[g];j;j--)
{
int tmp=;
for(int k=;k<=min(j,siz[nde]);k++)
if(j-k+<=siz[g])
tmp+=1ll*f[nde][k]*(f[g][siz[g]]-f[g][j-k]+mod)%mod*C(j-,k-)%mod*C(siz[nde]+siz[g]-j,siz[nde]-k)%mod,tmp%=mod;
f[nde][j]=tmp;
}
}
else
{
for(int j=siz[nde]+siz[g];j;j--)
{
int tmp=;
for(int k=;k<=min(j,siz[nde]);k++)
if(min(j-k,siz[g])>=)
tmp+=1ll*f[nde][k]*f[g][min(j-k,siz[g])]%mod*C(j-,k-)%mod*C(siz[nde]+siz[g]-j,siz[nde]-k)%mod,tmp%=mod;
f[nde][j]=tmp;
}
}
siz[nde]+=siz[g];
}
}
for(int i=;i<=siz[nde];i++)
f[nde][i]=(f[nde][i]+f[nde][i-])%mod;
}
int main()
{
Prework();
while(T--)
Init(),DFS(,),printf("%d\n",f[][n]);
return ;
}

最新文章

  1. 谷歌插件Image downloader开发之 content script
  2. 事务复制-大批量DEL操作
  3. csuoj 1337: 搞笑版费马大定理
  4. HDU 1087 Super Jumping! Jumping! Jumping
  5. Android——状态栏通知栏Notification
  6. 一步步学习PHP笔记(李炎恢瓢城web俱乐部-多用户留言系统)01
  7. OC-字典&amp;数组运用实例:通讯录的实现
  8. poj 3352 双连通分量
  9. Ubuntu16.04 install OpenJDK8
  10. MySQL命令(逐步更新ing)
  11. JavaScript splice() 、slice() 方法
  12. 一次 HTTP 请求响应过程的完整解析
  13. GitHub上好的Java项目
  14. .NET Core跨平台微服务学习资源
  15. Python-数学篇之计算方法的目录:
  16. python基础学习第六天
  17. ubuntu apache2下目录结构以及重写规则
  18. C++ classes and uniform initialization
  19. springmvc-servlet.xml中use-default-filters的作用
  20. mybatis generator配置,Mybatis自动生成文件配置,Mybatis自动生成实体Bean配置

热门文章

  1. P4562 [JXOI2018]游戏
  2. 04-matplotlib-柱形图
  3. NO.5:自学python之路------标准库,正则表达式
  4. fs - 文件系统
  5. “Hello World!”Final发布文案加美工
  6. 记事本App之NABCD
  7. Mac配置环境变量
  8. jmeter body 中文显示为乱码解决
  9. Dcoker中启动mysql,并实现root远程访问
  10. Asp.Net Core实现文件上传