【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. SDK Manager 闪退的解决方式

    打开电脑的执行  也就是win+R键    然后在命令行里面打上android即可了

  2. Mac删除.svn文件

    find . -type d -name ".svn"|xargs rm -rf

  3. C# Directory类的操作

    Directory类位于System.IO 命名空间.Directory类提供了在目录和子目录中进行创建移动和列举操作的静态方法.此外,你还可以访问和操作各种各样的目录属性,例如创建或最后一次修改时间 ...

  4. SQL server 2008定期的备份数据库及删除job

    在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求管理员 每天守到晚上1点去备份数据库.要实现数据库的 ...

  5. python开发者通过国内镜像安装pip包

    对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题.所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成 ...

  6. 异步FIFO的FPGA实现

    本文大部分内容来自Clifford E. Cummings的<Simulation and Synthesis Techniques for Asynchronous FIFO Design&g ...

  7. IBM websphere MQ 消息发送与获取

    一. 所需依赖包,安装 IBM websphere MQ 后,在安装目录下的 java 目录内 import java.io.IOException; import java.util.Propert ...

  8. How to Install Xcode, Homebrew, Git, RVM, Ruby & Rails on Snow Leopard, Lion, Mountain Lion, and Mavericks

    After following many outdated and incomplete instructions for setting up a web development environme ...

  9. Python正则表达式中的re.S的作用

    在Python的正则表达式中,有一个参数为re.S.它表示“.”(不包含外侧双引号,下同)的作用扩展到整个字符串,包括“\n”.看如下代码: import re a = '''asdfhellopas ...

  10. vue 的调试工具

    转载自:http://www.cnblogs.com/lolDragon/p/6268345.html 安装 1.github下载地址:https://github.com/vuejs/vue-dev ...