【BZOJ2616】SPOJ PERIODNI

Description

Input

第1行包括两个正整数N,K,表示了棋盘的列数和放的车数。 
第2行包含N个正整数,表示了棋盘每列的高度。

Output

包括一个非负整数,表示有多少种放置的方案,输出答案mod 
1000000007后的结果即可。

Sample Input

5 2
2 3 1 2 4

Sample Output

43

HINT

对于100%的数据,有 N≤500,K≤500,h[i] ≤1000000。

题解:一看题就感觉应该是单调栈什么的。。。具体地说,是笛卡尔树。于是学了一发笛卡尔树的建树方法,感觉跟建虚树差不多。

我们用一个栈来维护笛卡尔树上当前的一条链(向右的链),然后对于第i个点,我们看一下它会被插入到链的哪个位置,这个位置下面的点都连接到i的左儿子处,然后将i入栈。

本题的笛卡尔树要满足每个父亲的高度都比儿子小。

然后考虑树形DP,我们将笛卡尔树上的每个节点看成原图的一个矩形,它的上界是它自己的深度,下界是它父亲的深度,左右边界是它的子树范围。用f[x][y]表示在x的子树中放y个车使其互不影响的方案数。我们只需要考虑x对应的矩形中放多少点以及如何放即可。

用一点组合知识便可得到转移方程,设矩形的长为n,宽为m,当前儿子是a,则:

$f[x][y]=\sum\limits_{b}{f[a][y-b]*f[x][b]}$

再乘上矩形中如何放:

$f[x][z]=\sum\limits_{y}f[x][z-y]*y!C_{n-z+y}^yC_m^y$

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const ll P=1000000007;
int n,m,tot,top,rt;
ll f[510][510],jc[1000010],ine[1000010],jcc[1000010],g[510];
int st[510],fa[510],v[510],ch[510][2];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline ll c(int a,int b)
{
if(a<b) return 0;
return jc[a]*jcc[a-b]%P*jcc[b]%P;
}
int dfs(int x)
{
int a=1,b=v[x]-v[fa[x]],i,j,k,y,aa;
f[x][0]=1;
for(i=0;i<=1;i++) if(ch[x][i])
{
y=ch[x][i],aa=dfs(y);
memset(g,0,sizeof(g));
for(j=0;j<=a;j++) for(k=0;k<=aa&&j+k<=m;k++) g[j+k]=(g[j+k]+f[x][j]*f[y][k])%P;
a+=aa;
for(j=0;j<=a;j++) f[x][j]=g[j];
}
for(i=min(m,a);i>=0;i--)
{
ll tmp=0;
for(j=0;j<=i;j++) tmp=(tmp+f[x][i-j]*jc[j]%P*c(a-i+j,j)%P*c(b,j)%P)%P;
f[x][i]=tmp;
}
return a;
}
int main()
{
n=rd(),m=rd();
int i,a;
for(i=1;i<=n;i++) v[i]=rd();
ine[0]=ine[1]=jc[0]=jc[1]=jcc[0]=jcc[1]=1;
for(i=2;i<=1000000;i++) jc[i]=jc[i-1]*i%P,ine[i]=(P-ine[P%i]*(P/i)%P)%P,jcc[i]=jcc[i-1]*ine[i]%P;
for(i=1;i<=n;i++)
{
while(top&&v[st[top]]>v[i])
{
a=st[top],top--;
if(top&&v[st[top]]>v[i]) ch[st[top]][1]=a,fa[a]=st[top];
else ch[i][0]=a,fa[a]=i;
}
st[++top]=i;
}
while(top>1) ch[st[top-1]][1]=st[top],fa[st[top]]=st[top-1],top--;
rt=st[1],dfs(rt);
printf("%lld",f[rt][m]);
return 0;
}

【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP的更多相关文章

  1. bzoj 2616 SPOJ PERIODNI——笛卡尔树+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2616 把相同高度的连续一段合成一个位置(可能不需要?),用前缀和维护宽度. 然后每次找区间里 ...

  2. BZOJ.2616.SPOJ PERIODNI(笛卡尔树 树形DP)

    BZOJ SPOJ 直观的想法是构建笛卡尔树(每次取最小值位置划分到两边),在树上DP,这样两个儿子的子树是互不影响的. 令\(f[i][j]\)表示第\(i\)个节点,放了\(j\)个车的方案数. ...

  3. bzoj2616: SPOJ PERIODNI——笛卡尔树+DP

    不连续的处理很麻烦 导致序列DP又找不到优秀的子问题 自底向上考虑? 建立小根堆笛卡尔树 每个点的意义是:高度是(自己-father)的横着的极大矩形 子问题具有递归的优秀性质 f[i][j]i为根子 ...

  4. BZOJ2616 SPOJ PERIODNI(笛卡尔树+树形dp)

    考虑建一棵小根堆笛卡尔树,即每次在当前区间中找到最小值,以最小值为界分割区间,由当前最小值所在位置向两边区间最小值所在位置连边,递归建树.那么该笛卡尔树中的一棵子树对应序列的一个连续区间,且根的权值是 ...

  5. BZOJ2616 SPOJ PERIODNI(笛卡尔树 + DP)

    题意 N,K≤500,h[i]≤106N,K\le 500,h[i]\le10^6N,K≤500,h[i]≤106 题解 建立出小根堆性质的笛卡尔树,于是每个节点可以代表一个矩形,其宽度为子树大小,高 ...

  6. [BZOJ2616]SPOJ PERIODNI 树形dp+组合数+逆元

    2616: SPOJ PERIODNI Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 128  Solved: 48[Submit][Status][ ...

  7. NOIP2011pj表达式的值[树形DP 笛卡尔树 | 栈 表达式解析]

    题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × ...

  8. 洛谷 P5044 - [IOI2018] meetings 会议(笛卡尔树+DP+线段树)

    洛谷题面传送门 一道笛卡尔树的 hot tea. 首先我们考虑一个非常 naive 的区间 DP:\(dp_{l,r}\) 表示区间 \([l,r]\) 的答案,那么我们考虑求出 \([l,r]\) ...

  9. TopCoder 14084 BearPermutations2【笛卡尔树+dp】

    传送:https://vjudge.net/problem/TopCoder-14084 只是利用了笛卡尔树的性质,设f[i][j]为区间[i,j]的贡献,然后枚举中间最大的点k来转移,首先是两侧小区 ...

随机推荐

  1. 解析URL中的携带的参数到Map

    手动解析URL字符串中的参数,写了一个工具类. final ; final ; public Map<String, String> parseRequestParam(String ur ...

  2. NAT Network Address Translation,网络地址转换

    Network Address Translation,网络地址转换

  3. atitit.软件gui按钮and面板---os区-----软链接,快捷方式

    atitit.软件gui按钮and面板---os区-----软链接,快捷方式 1. 硬链接 1 2. 二.软链接(符号链接)LN 1 3. 三.删除链接 2 4. 区别 2 5. 参考 3 1. 硬链 ...

  4. redmine 的安装

    https://bitnami.com/stack/redmine/installer#官方地址 安装很简单,给权限 chmod +x bitnami-redmine-3.3.0-1-linux-x6 ...

  5. json对象与json字符串互转方法

    jQuery插件支持的转换方式: 复制代码 代码如下: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 ...

  6. 让低版本IE也能正常运行HTML5+CSS3网站的3种解决方案

    现在我们可以选择浏览器非常多,所以浏览器的环境也是种类繁多,同一个浏览器也是包含各种不同的版本,不同的版本之间的渲染方法也存在差异,,它们支持的 HTML5.CSS3 特性恐怕也不尽相同.这种情况于是 ...

  7. 线程相关函数(5)-pthread_rwlock_rdlock(),pthread_rwlock_wrlock() 读写锁

    读共享,写独占 pthread_rwlock_tpthread_rwlock_initpthread_rwlock_destroypthread_rwlock_rdlockpthread_rwlock ...

  8. CXF学习笔记 之 “注解”

    @WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值为 Java 类的简单名称 + Service.(字符 ...

  9. WWDC 2014 Session笔记 - iOS界面开发的大一统

    本文是我的 WWDC 2014 笔记 中的一篇,涉及的 Session 有 What's New in Cocoa Touch Building Adaptive Apps with UIKit Wh ...

  10. 李洪强iOS经典面试题35-按层遍历二叉树的节点

    李洪强iOS经典面试题35-按层遍历二叉树的节点 问题 给你一棵二叉树,请按层输出其的节点值,即:按从上到下,从左到右的顺序. 例如,如果给你如下一棵二叉树:    3   / \  9  20   ...