luogu P4099 [HEOI2013]SAO
这个依赖关系是个树,可以考虑树型dp,设f_i表示子树i的答案
因为这是个序列问题,是要考虑某个数的位置的,所以设\(f_{i,j}\)表示子树i构成的序列,i在第j个位置的方案.转移依次合并儿子\(y\),每次枚举一个位置j,以及枚举儿子\(y\)的序列中有k个数放在插前面,可以得到\(f_{x,j+k}\leftarrow f_{x,j}*w*\binom{j-1+k}{k}*\binom{sz_x+sz_y-j-k}{sz_y-k}\),组合数即考虑插入的方式
还有一个w不知道,如果要求\(x\)在\(y\)前面,那么\(y\)要在自己子树序列的\(k+1\)位置及以后所以\(w=\sum_{i=k+1}^{sz_y} f_{y,i}\),否则要在\(k\)及以前,所以\(w=\sum_{i=1}^{k} f_{y,i}\),显然可以记前缀和
最后答案为根的dp值总和.注意到合并复杂度,这些合并等价于每个点对都在lca处贡献一个\(O(1)\),所以总复杂度为\(O(n^2)\)
#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register
using namespace std;
const int N=1000+10,mod=1e9+7;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],w[N<<1],hd[N],tot=1;
il void add(int x,int y,int z)
{
++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],w[tot]=z^1,hd[y]=tot;
}
int c[N][N],f[N][N],g[N],sz[N],pr[N][N],sf[N][N];
void dp(int x,int ffa)
{
sz[x]=1;
f[x][1]=1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==ffa) continue;
dp(y,x),sz[x]+=sz[y];
memset(g,0,sizeof(g));
if(w[i]==0)
{
for(int j=sz[x]-sz[y];j;--j)
for(int k=0;k<=sz[y];++k)
g[j+k]=(g[j+k]+1ll*f[x][j]*c[j-1+k][k]%mod*c[sz[x]-j-k][sz[y]-k]%mod*sf[y][k+1]%mod)%mod;
}
else
{
for(int j=sz[x]-sz[y];j;--j)
for(int k=0;k<=sz[y];++k)
g[j+k]=(g[j+k]+1ll*f[x][j]*c[j-1+k][k]%mod*c[sz[x]-j-k][sz[y]-k]%mod*pr[y][k]%mod)%mod;
}
memcpy(f[x],g,sizeof(g));
}
for(int i=1;i<=sz[x];++i) pr[x][i]=(pr[x][i-1]+f[x][i])%mod;
sf[x][sz[x]+1]=0;
for(int i=sz[x];i;--i) sf[x][i]=(sf[x][i+1]+f[x][i])%mod;
}
int main()
{
for(int i=0;i<=1000;++i)
{
c[i][0]=1;
for(int j=1;j<=i;++j) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
int T=rd();
while(T--)
{
memset(f,0,sizeof(f));
memset(hd,0,sizeof(hd)),tot=1;
int n=rd();
for(int i=1;i<n;++i)
{
int x=rd()+1,z=(getchar())=='>',y=rd()+1;
add(x,y,z);
}
dp(1,0);
int ans=0;
for(int i=1;i<=n;++i) ans=(ans+f[1][i])%mod;
printf("%d\n",ans);
}
return 0;
}
luogu P4099 [HEOI2013]SAO的更多相关文章
- P4099 [HEOI2013]SAO
P4099 [HEOI2013]SAO 贼板子有意思的一个题---我()竟然没看题解 有一张连成树的有向图,球拓扑序数量. 树形dp,设\(f[i][j]\)表示\(i\)在子树中\(i\)拓扑序上排 ...
- P4099 [HEOI2013]SAO(树形dp)
P4099 [HEOI2013]SAO 我们设$f[u][k]$表示以拓扑序编号为$k$的点$u$,以$u$为根的子树中的元素所组成的序列方案数 蓝后我们在找一个以$v$为根的子树. 我们的任务就是在 ...
- [BZOJ3167][P4099][HEOI2013]SAO(树形DP)
题目描述 Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...
- 洛谷 P4099 - [HEOI2013]SAO(树形 dp)
题面传送门 题意: 有一个有向图 \(G\),其基图是一棵树 求它拓扑序的个数 \(\bmod (10^9+7)\) \(n \in [1,1000]\) 如果你按照拓扑排序的方法来做,那恐怕你已经想 ...
- 洛谷P4099 [HEOI2013]SAO(树形dp)
传送门 HEOI的题好珂怕啊(各种意义上) 然后考虑树形dp,以大于为例 设$f[i][j]$表示$i$这个节点在子树中排名第$j$位时的总方案数(因为实际只与相对大小有关,与实际数值无关) 我们考虑 ...
- 洛谷$P4099\ [HEOI2013]\ SAO\ dp$
正解:树形$dp$ 解题报告: 传送门$QwQ$. 考虑设$f_i$表示点$i$的子树内的拓扑序排列方案数有多少个. 发现这样不好合并儿子节点和父亲节点.于是加一维,设$f_{i,j}$表示点$i$的 ...
- 【做题记录】 [HEOI2013]SAO
P4099 [HEOI2013]SAO 类型:树形 \(\text{DP}\) 这里主要补充一下 \(O(n^3)\) 的 \(\text{DP}\) 优化的过程,基础转移方程推导可以参考其他巨佬的博 ...
- 3167: [Heoi2013]Sao [树形DP]
3167: [Heoi2013]Sao 题意: n个点的"有向"树,求拓扑排序方案数 Welcome to Sword Art Online!!! 一开始想错了...没有考虑一个点 ...
- 【BZOJ3167】[HEOI2013]SAO(动态规划)
[BZOJ3167][HEOI2013]SAO(动态规划) 题面 BZOJ 洛谷 题解 显然限制条件是一个\(DAG\)(不考虑边的方向的话就是一棵树了). 那么考虑树型\(dp\),设\(f[i][ ...
随机推荐
- 真的无语, 今天遇到一个奇葩的事情: http 会话劫持
今天一个用户反应说软件一运行就提示错误,然后关闭. 然后用户截屏发给我看了一下,我一看,无语了. 在软件中显示的正常一段文字说明尾部出现 <script src="http://ad. ...
- 将vcf文件转化为plink格式并且保持phasing状态
VCFtools can convert VCF files into formats convenient for use in other programs. One such example i ...
- postman 测试套件collection
测试套件collection就是为了跑一套case,整体的一套case,为了解决一个一个的case单独跑 1.点击小加号 2.填写套件的名字 3.右键增加folder,一个folder里面可以增加多个 ...
- C++基础知识-Day5
今天主要讲的是类的扩展 1.类成员函数的存储方式 首先我们介绍类成员函数的存储方式,C++引入面向对象的概念之后,C语言中的一些比如static/const等原有语义,作一些升级,此时既要保持兼容,还 ...
- hdu 4283"You Are the One"(区间DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题意: 有n个屌丝排成一排,每个屌丝都有一个不开心值a[ i ]( i=1,2,3,.. ...
- SQL Server 经典案例
1.先进先出 例1 WITH [ta] ([商品编号], [批次号], [库存数量]) AS ( UNION ALL UNION ALL UNION ALL ),[tb] ([商品编号], [订货数量 ...
- lucene之中文分词及其高亮显示(五)
中文分词:即换个分词器 Analyzer analyzer = new StandardAnalyzer();// 标准分词器 换成 SmartChineseAnalyzer analyze ...
- Python中集合的操作
Python集合的基本详情 集合是无序的 集合是可变数据类型 集合属于不可哈希范围 集合自动去重 集合的操作 set1 = {1, 2, 3, 4, 5} set2 = {4, 5, 6, 7, 8} ...
- Java中的Dom4j
上一篇讲了Java中如何操作XML,现在介绍一个更厉害的方法,Dom4j ,百度查一下就知道,这个更强,更快,更简单. 自己下载jar包导入工具,下面来讲一个例子,我事先准备了一个XML文件,如下: ...
- 8.装饰模式(Decorator Pattern)
子类复子类,子类何其多 假如我们需要为游戏中开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合中为其增加以下一种或多种功能;比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等等.按类继 ...