3167: [Heoi2013]Sao

题意:

n个点的“有向”树,求拓扑排序方案数


Welcome to Sword Art Online!!!


一开始想错了...没有考虑一个点的孩子可以排在父亲后...


为了能转移,给状态加一维,\(f[i][j]\)表示子树i,i排在第j位的方案数

然后,很像树形背包啊,转移枚举孩子子树中k个点在i之前,更新\(f[i][j+k]\)

严格做到每次合并复杂度为 “已经合并大小*正要合并进去的大小”,那么这个复杂度就是\(O(n^2)\)的,因为一个点对只贡献一次

真不敢相信我以前的树形背包都写的是\(O(n^3)\)


注意需要用一个新数组保存当前更新得到的值

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1005, P = 1e9+7;
inline int read() {
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
} int n, u, v, c[N][N];
char s[5];
struct edge{int v, ne, p;} e[N<<1];
int cnt, h[N];
inline void ins(int u, int v) { //printf("ins %d %d\n", u, v);
e[++cnt] = (edge){v, h[u], 1}; h[u] = cnt;
e[++cnt] = (edge){u, h[v], 0}; h[v] = cnt;
}
int f[N][N], size[N], f_pre[N][N], f_suf[N][N], g[N];
void dp(int u, int fa) {
size[u] = 1; f[u][1] = 1;
for(int i=h[u]; i; i=e[i].ne) {
int v = e[i].v, p = e[i].p;
if(v == fa) continue;
dp(v, u);
for(int j = 0; j <= size[u] + size[v]; j++) g[j] = 0;
for(int j = 1; j <= size[u]; j++)
for(int k = 0; k <= size[v]; k++) {
ll t = p ? f_suf[v][k+1] : f_pre[v][k];
g[j+k] = (g[j+k] + (ll) c[j-1+k][k] * c[size[u]-j+size[v]-k][size[v]-k] %P * f[u][j] %P * t) %P;
}
for(int j = 0; j <= size[u] + size[v]; j++) f[u][j] = g[j];
size[u] += size[v];
}
for(int i = 1; i <= size[u]; i++) f_pre[u][i] = (f_pre[u][i-1] + f[u][i]) %P;
for(int i = size[u]; i >= 1; i--) f_suf[u][i] = (f_suf[u][i+1] + f[u][i]) %P;
}
int main() {
freopen("in", "r", stdin);
int T = read();
c[0][0] = 1;
for(int i=1; i<N; i++) {
c[i][0] = 1;
for(int j=1; j<N; j++) c[i][j] = (c[i-1][j] + c[i-1][j-1]) %P;
}
while(T--) {
n = read();
memset(f, 0, sizeof(f));
memset(f_pre, 0, sizeof(f_pre));
memset(f_suf, 0, sizeof(f_suf));
cnt = 0; memset(h, 0, sizeof(h));
for(int i=1; i<n; i++) {
u = read()+1; scanf("%s", s); v = read()+1;
if(s[0] == '<') ins(u, v); else ins(v, u);
}
dp(1, 0);
printf("%d\n", f_pre[1][size[1]]);
}
}

3167: [Heoi2013]Sao [树形DP]的更多相关文章

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

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

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

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

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

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

  4. BZOJ 3167: [Heoi2013]Sao

    3167: [Heoi2013]Sao Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 96  Solved: 36[Submit][Status][D ...

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

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

  6. [BZOJ3167][HEOI2013]SAO[树dp+组合数学]

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

  7. [BZOJ4824][CQOI2017]老C的键盘(树形DP)

    4824: [Cqoi2017]老C的键盘 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 193  Solved: 149[Submit][Statu ...

  8. [提升性选讲] 树形DP进阶:一类非线性的树形DP问题(例题 BZOJ4403 BZOJ3167)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7337179.html 树形DP是一种在树上进行的DP相对比较难的DP题型.由于状态的定义多种多样,因此解法也五 ...

  9. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

随机推荐

  1. 使用npm install报错-4048 operation not permitted解决

    刚刚使用npm install时一直报错-4048 operation not permitted,也尝试了多种方法,终于使问题得到解决,这里总结几种方法,先贴图: 一:权限问题 首先看到operat ...

  2. 【django基础补充之URL,视图,模版】

    一.url路由配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代 ...

  3. 逢三退一(boolean数组的使用)

    package com.hanqi.count; // 逢三退一 输出留到最后值的索引; public class Count1 { //主方法 public static void main(Str ...

  4. [转载]织梦CMS首页调用分类信息栏目及列表方法

    原文地址:织梦CMS首页调用分类信息栏目及列表方法作者:小武哥 不懂代码,搜索学习一晚上,都是说调用特定栏目分类信息列表的,用这个代码 {dede:arclistsg row='10' titlele ...

  5. NGINX 配置404错误页面转向

    什么是404页面 如果碰巧网站出了问题,或者用户试图访问一个并不存在的页面时,此时服务器会返回代码为404的错误信息,此时对应页面就是404页面.404页面的默认内容和具体的服务器有关.如果后台用的是 ...

  6. OKMX6Q在ltib生成的rootfs基础上制作带QT库的根文件系统

    ltib每次执行后会在其目录下生成rootfs目录,并以其为基础生成rootfs.ext2.gz文件,而litb自带的QT库又太老,所以想到按照飞凌的<OKMX6X-S2-Qt4.8.5移植手册 ...

  7. servlet入门学习之工作原理解析

    从 Servlet 容器说起 要介绍 Servlet 必须要先把 Servlet 容器说清楚,Servlet 与 Servlet 容器的关系有点像枪和子弹的关系,枪是为子弹而生,而子弹又让枪有了杀伤力 ...

  8. c#套料程序设计

    上的套料基本上都没有源码,开放的sdk都没有,这让很多想做套料,但是又成本太高了. 另外,大部分套料都是c++实现的,效率高,本人尝试用c#做一个套料程序,发现效率也不低,当然会比c++差点. 以下是 ...

  9. JS-输入金额校验

    function clearNoNum(obj){    obj.value = obj.value.replace(/[^\d.]/g,"");  //清除"数字&qu ...

  10. [one day one question] webpack打包压缩 ES6 js、.vue报错

    问题描述: 报错: ERROR in js/test.js from UglifyJs Unexpected token punc ?(?, expected punc ?:? [js/test.js ...