题意

给定 \(n\) 个节点和 \(n-1\) 个限制,每个节点有一个权值,每个限制形如:\(a_i< a_j\) ,问有多少个 \(1\) 到 \(n\) 排列满足要求。

\(n\leq 1000\) 。

分析

  • 猜测复杂度为 \(O(n^2)\) ,并且应该要看成是树形结构。

  • 定义状态 \(f_{i,j}\) 表示以 \(i\) 为根的子树内有 \(j\) 个节点权值 \(< a_i\)的合法方案数。

  • 考虑转移,记 \(v\) 为 \(u\) 的儿子,有两种情况:

  • \(a_u > a_v\)

\[f_{u,j+k}=\binom{j+k}{k}\binom{{son}_u+{son}_v-1-j-k}{{son}_v-k}*f_{u,j}*\sum_{x=0}^{k-1}f_{v,x}
\]

  • \(a_u < a_v\)

\[f_{u,j+k}=\binom{j+k}{k}\binom{{son}_u+{son}_v-1-j-k}{{son}_v-k}*f_{u,j}*\sum_{x=k}^{{son}_v-1}f_{v,x}
\]

  • 总时间复杂度为 \(O(n^2)\) 。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
#define re(x) memset(x,0,sizeof x)
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e3 + 7,mod=1e9 + 7;
int T,n,edc;
int head[N],c[N][N],f[N][N],s[N],son[N],g[N];
char str[10];
struct edge{
int last,to,c;
edge(){}edge(int last,int to,int c):last(last),to(to),c(c){}
}e[N*2];
void Add(int a,int b,int c){
e[++edc]=edge(head[a],b,c),head[a]=edc;
e[++edc]=edge(head[b],a,c^1),head[b]=edc;
}
void add(int &a,int b){a+=b;if(a>=mod) a-=mod;}
void init(){
re(head),re(f);edc=0;
}
void dfs(int u,int fa){
son[u]=f[u][0]=1;
go(u)if(v^fa){
dfs(v,u); re(s);re(g);
if(e[i].c==0){
for(int x=0;x<son[v];++x) s[x]=((x?s[x-1]:0)+f[v][x])%mod;
for(int tv=son[u]-1;~tv;--tv)
for(int b=son[v];b;--b)
add(g[tv+b],1ll*c[tv+b][b]*c[son[u]+son[v]-1-tv-b][son[v]-b]%mod*f[u][tv]%mod*s[b-1]%mod);
}else{
for(int x=son[v]-1;~x;--x) s[x]=(s[x+1]+f[v][x])%mod;
for(int tv=son[u]-1;~tv;--tv)
for(int b=son[v]-1;~b;--b)
add(g[tv+b],1ll*c[tv+b][b]*c[son[u]+son[v]-1-tv-b][son[v]-b]%mod*f[u][tv]%mod*s[b]%mod);
}
memcpy(f[u],g,sizeof g);
son[u]+=son[v];
}
}
void work(){
n=gi();
for(int i=1,a,b,c;i<n;++i){
scanf("%d%s%d",&a,str,&b);
c=str[0]=='>'?0:1;
Add(a+1,b+1,c);
}
dfs(1,0);int ans=0;
rep(i,0,n) add(ans,f[1][i]);
printf("%d\n",ans);
}
int main(){
rep(i,0,N-1){
c[i][0]=1;
rep(j,1,i) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
T=gi();
while(T--) init(),work();
return 0;
}

[BZOJ3167][HEOI2013]SAO[树dp+组合数学]的更多相关文章

  1. 3167: [Heoi2013]Sao [树形DP]

    3167: [Heoi2013]Sao 题意: n个点的"有向"树,求拓扑排序方案数 Welcome to Sword Art Online!!! 一开始想错了...没有考虑一个点 ...

  2. [HEOI2013]SAO(树上dp,计数)

    [HEOI2013]SAO (这写了一个晚上QAQ,可能是我太蠢了吧.) 题目说只有\(n-1\)条边,然而每个点又相互联系.说明它的结构是一个类似树的结构,但是是有向边连接的,题目问的是方案个数,那 ...

  3. [BZOJ3167][P4099][HEOI2013]SAO(树形DP)

    题目描述 Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...

  4. bzoj3167 [Heoi2013]Sao

    传送门 这题神坑啊……明明是你菜 首先大家都知道原题等价于给每个点分配一个$1$~$n$且两两不同的权值,同时还需要满足一些大于/小于关系的方案数. 先看一眼数据范围,既然写明了$n\le 1000$ ...

  5. BZOJ 3167 [Heoi2013]Sao ——树形DP

    BZOJ4824的强化版. 改变枚举的方案,使用前缀和进行DP优化. 然后复杂度就是$O(n^2)$了. #include <map> #include <cmath> #in ...

  6. 洛谷 4099 [HEOI2013]SAO——树形DP

    题目:https://www.luogu.org/problemnew/show/P4099 结果还是看了题解才会…… 关键是状态,f[ i ][ j ] 表示 i 子树. i 号点是第 j 个出现的 ...

  7. 【BZOJ3167】[HEOI2013]SAO(动态规划)

    [BZOJ3167][HEOI2013]SAO(动态规划) 题面 BZOJ 洛谷 题解 显然限制条件是一个\(DAG\)(不考虑边的方向的话就是一棵树了). 那么考虑树型\(dp\),设\(f[i][ ...

  8. 【BZOJ3167/4824】[Heoi2013]Sao/[Cqoi2017]老C的键盘

    [BZOJ3167][Heoi2013]Sao Description WelcometoSAO(StrangeandAbnormalOnline).这是一个VRMMORPG,含有n个关卡.但是,挑战 ...

  9. P4099 [HEOI2013]SAO(树形dp)

    P4099 [HEOI2013]SAO 我们设$f[u][k]$表示以拓扑序编号为$k$的点$u$,以$u$为根的子树中的元素所组成的序列方案数 蓝后我们在找一个以$v$为根的子树. 我们的任务就是在 ...

随机推荐

  1. [翻译] SSKeychain

    SSKeychain https://github.com/soffes/sskeychain SSKeychain is a simple wrapper for accessing account ...

  2. 题解 P1894 【[USACO4.2]完美的牛栏The Perfect Stall】

    题面 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们 ...

  3. 【Alpha】Daily Scrum Meeting——blog2

    团队成员 吴吉键 201421122007(组长) 魏修祺 201421122008 孙劲林 201421122022 1. 会议当天照片 忘记拍了!(没有拍照片的习惯,没有第四人拍照) 2. 每个人 ...

  4. 字典树(前缀树)-Java实现

    字典树 字典树是一种树形结构,优点是利用字符串的公共前缀来节约存储空间.在这提供一个自己写的Java实现,非常简洁. 根节点没有字符路径.除根节点外,每一个节点都被一个字符路径找到. 从根节点到某一节 ...

  5. QT里使用Gsoap调用WebService

    错误了很多天,今天终于搞定,并得到了服务器的结果.这里把错误的原因记录下来. 首先是这里,之前一直没有加载进来,所以一直报错 SOURCES += main.cpp\ gsoap/soapClient ...

  6. 【洛谷】【lca+结论】P3398 仓鼠找sugar

    [题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...

  7. Linux - Confluence搭建

    0. 摘要 Confluence自身携带内置数据库,对于生产环境建议搭建外置数据库,Confluence通过相应驱动连接上.并操作数据库.Confluence支持多种数据库,本文采用MySQL. 1. ...

  8. VMware虚拟机安装Mac OS X

    安装mac系统学习网站来源:http://blog.csdn.net/hamber_bao/article/details/51335834 1.下载安装VMware workstation (1)首 ...

  9. 多线程之Thread类

    Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...

  10. winform程序打包成exe文件

    拿到一个实现功能的winform小程序,如何利用NSIS工具制作安装包? 1.NSIS工具下载地址 点我下载 2.启动NSIS工具,如图点击 3.选择"使用脚本向导创建新的脚本文件" ...