题面

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

设$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 ;
}

解题:HEOI 2013 SAO的更多相关文章

  1. [BZOJ 3167][HEOI 2013]SAO

    [BZOJ 3167][HEOI 2013]SAO 题意 对一个长度为 \(n\) 的排列作出 \(n-1\) 种限制, 每种限制形如 "\(x\) 在 \(y\) 之前" 或 & ...

  2. [HEOI 2013]SAO

    Description 题库连接 给你一个 \(n\) 个节点的有向树,问你这棵树的拓扑序个数,对大质数取模.多测,测试组数 \(T\). \(1\leq n\leq 1000, 1\leq T\le ...

  3. [HEOI 2013 day2] SAO (树形动态规划)

    题目大意 给一棵N个节点的有向树(N <= 1000),求其拓扑序列个数. 思路 我们将任意一个点作为根,用dp[i][j]表示以节点i为根的子树满足节点i在第j个位置上的拓扑序列的个数.在求节 ...

  4. 【BZOJ 3165】【HEOI 2013】Segment

    往区间上覆盖一次函数,做法是用线段树维护标记永久化. 每次都忘了线段树要4倍空间,第一次交总是RE,再这么手残的话考场上就真的要犯逗了. #include<cstdio> #include ...

  5. [HEOI 2013 day2] 钙铁锌硒维生素 (线性代数,二分图匹配)

    题目大意 给定两个n阶方阵,方阵B的行i能匹配方阵A的行j当且仅当在第一个方阵中用行向量i替换行向量j后,第一个方阵满秩,显然这是个二分图匹配问题,问是否存在完美匹配,如果存在,还要输出字典序最小的方 ...

  6. 【BZOJ 3166】【HEOI 2013】Alo

    http://www.lydsy.com/JudgeOnline/problem.php?id=3166 这道题难点在于求能对一个次大值有贡献的区间. 设这个次大值为\(a_i\),\(a_i\)左边 ...

  7. [总结]一些 DP 优化方法

    目录 注意本文未完结 写在前面 矩阵快速幂优化 前缀和优化 two-pointer 优化 决策单调性对一类 1D/1D DP 的优化 \(w(i,j)\) 只含 \(i\) 和 \(j\) 的项--单 ...

  8. poj 2013 Symmetric Order 解题报告

    题目链接:http://poj.org/problem?id=2013 设长度非递减的字串序列为s[1]...s[n].设计递归子程序print(n),其中n为字串序号,每分析1个字串,n=n-1. ...

  9. HNU 13064 Cuckoo for Hashing解题报告 North America - East Central 2013

    题目大意:使用两个哈希表来解决哈希冲突的问题.假如现在有两个哈希表分别为:H1,H2 ,大小分别为:n1,n2:现有一数据X需要插入,其插入方法为: 1.计算index1 = X MOD N1,  若 ...

随机推荐

  1. Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化

    Netty源码分析第一章:  Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的 ...

  2. jQuery的基本使用

    一.jQuery简介 jQuery是一个快速.简洁的JavaScript框架,它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作.事件处理.动 ...

  3. netcore如何引用package?

    netcore项目引用dll包,分如下三种: 1.引用网络包 从nuget获取,然后引入,使用命令:dotnet add package 包名 然后:dotnet restore 2.引用同解决方案的 ...

  4. js 的filter()方法

    filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. filter()基本语法: arr.filter(callback[, thisArg]) filter() ...

  5. 软件工程-东北师大站-第十次作业(PSP)

    1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 4.本周PSP饼状图

  6. java-switch语句

    switch语句是常用的java循环判断语句,但是有的知识点并不一定清楚. 首先是switch语句括号中的判断条件,判断条件只能是整型或者字符和整型或者字符组成的表达式. 再就是case语句,可以称之 ...

  7. fragment的学习

    这个讲的不错 http://blog.csdn.net/lmj623565791/article/details/37992017  Fragment与Activity交互的几种方式(二,使用Bund ...

  8. cobbler技术详解(是PXE二次详解)

    Cobbler是PXE的二次封装,使用Python语言开发, 可以用来快速建立 Linux 网络安装环境,它已将 Linux 网络安装的技术门槛,从大专以上文化水平,成功降低到初中以下,连补鞋匠都能学 ...

  9. lr常见问题汇总(持续更新版)

    在使用mms协议的时候,会碰到报错 Action.c(): 错误: C 解释器运行时错误: Action.c (): Error -- Unresolved symbol : mms_play. 解决 ...

  10. linux_添加定时任务,每5min清理下某个文件夹下的文件

    性能测试的过程中会生成大量的日志文件,导致无法继续进行,linux可以增加一个定时任务,进行定时清理 1. 先编写一个sh脚本,该sh脚本用于文件夹文件清理,脚本编写完成后拷贝到服务器上,且授予权限 ...