题面

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

设$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源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第6节: 异线程回收对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第六节: 异线程回收对象 异线程回收对象, 就是创建对象和回收对象不在同一条线程的情况下, 对象回收的逻辑 我 ...

  2. 图-最小生成树算法之Kruskal及其Java实现

    1.Kruskal算法 Kruskal算法基于贪心,因此它追求的是近似最优解,也就是说由Kruskal得出的生成树并不一定是最优解. Kruskal算法求最小生成树的关键在于,每次选取图中权值最小(及 ...

  3. ssm-maven 所需添加的所有映射

    <dependencies> <!--Mybatis依赖--> <dependency> <groupId>org.mybatis</groupI ...

  4. nodejs的Cannot find module 'body-parser'

    http://blog.csdn.net/u014345860/article/details/77769253

  5. 团队博客作业Week4 --- 学霸网站--NABC

    1.需求(Need) 伴随着经济的发展,科学技术取得了飞速的发展,互联网在各行各业的发展中取得了广泛的应用.随着这些事物的发展,我们每个人都会接触到相当庞大的数据.如何在这些数据中找到自己需要的,如何 ...

  6. 1、数据库与excel表格的数据导入导出

    1.居民用户界面中,excel数据导入导出: 2.其他5张表数据显示到本角色主页的container容器中.

  7. <构建之法>阅读感想

    在阅读<构建之法>之前,我所认为的软件就是通过c,c++等语言编程,制作出的一个能满足人们操作需求的一些代码,认为一个好的软件工程师,就是能够在很短的时间之内,最快的根据需求写出几段代码程 ...

  8. c++第七次作业____最后的总结

    先言: 在这过程中学到: 第二次作业Github的使用 第四次作业计算器的计算 ps:表达式处理以及计算 第五次作业文件的处理问题 第六次作业界面的设计 总结: 1.这学期的计算器,做的有点匆忙,偶尔 ...

  9. Socket 记录

    心跳检测步骤:1客户端每隔一个时间间隔发生一个探测包给服务器2客户端发包时启动一个超时定时器3服务器端接收到检测包,应该回应一个包4如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器5如果 ...

  10. printf in KEIL C51

    转自:http://blog.csdn.net/it1988888/article/details/8821713 在keil中printf默认是向串口中发送数据的,所以,如果应用该函数,必须先初始化 ...