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

  在笛卡尔树上跑树形dp。设f[i][j]为在i子树对应棋盘中放j个车的方案数,且棋盘中只考虑这段区间在根的父亲高度上方的部分。转移考虑合并两棵子树再在新增加的矩形部分放车即可,捣鼓一下组合数。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 510
#define P 1000000007
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a[N],son[N][2],size[N],fa[N],f[N][N],root;
int fac[1000010],inv[1000010];
int build(int l,int r)
{
if (l==r) {size[l]=1;return l;}
int mx=l;
for (int i=l+1;i<=r;i++) if (a[i]<a[mx]) mx=i;
if (l<mx) son[mx][0]=build(l,mx-1);
if (mx<r) son[mx][1]=build(mx+1,r);
fa[son[mx][0]]=fa[son[mx][1]]=mx;
size[mx]=size[son[mx][0]]+size[son[mx][1]]+1;
return mx;
}
void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
int C(int n,int m){if (m>n) return 0;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
void dfs(int k)
{
if (son[k][0]) dfs(son[k][0]);
if (son[k][1]) dfs(son[k][1]);
for (int i=0;i<=m;i++)
for (int j=0;j<=i;j++)
inc(f[k][i],1ll*f[son[k][0]][j]*f[son[k][1]][i-j]%P);
int h=a[k]-a[fa[k]];
for (int i=m;i>=0;i--)
for (int j=min(size[k],i-1);j>=0;j--)
inc(f[k][i],1ll*f[k][j]*C(size[k]-j,i-j)%P*C(h,i-j)%P*fac[i-j]%P);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2616.in","r",stdin);
freopen("bzoj2616.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read();
root=build(1,n);f[0][0]=1;
fac[0]=1;for (int i=1;i<=1000000;i++) fac[i]=1ll*fac[i-1]*i%P;
inv[0]=inv[1]=1;for (int i=2;i<=1000000;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
for (int i=2;i<=1000000;i++) inv[i]=1ll*inv[i-1]*inv[i]%P;
dfs(root);
cout<<f[root][m];
return 0;
}

  

BZOJ2616 SPOJ PERIODNI(笛卡尔树+树形dp)的更多相关文章

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

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

  2. 【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP

    [BZOJ2616]SPOJ PERIODNI Description Input 第1行包括两个正整数N,K,表示了棋盘的列数和放的车数. 第2行包含N个正整数,表示了棋盘每列的高度. Output ...

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

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

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

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

  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. Sparse Principal Component Analysis via Rotation and Truncation

    目录 对以往一些SPCA算法复杂度的总结 Notation 论文概述 原始问题 问题的变种 算法 固定\(X\),计算\(R\) 固定\(R\),求解\(X\) (\(Z =VR^{\mathrm{T ...

  2. git在vs2017中的使用

    对于习惯了右键提交源代码的道友来说,敲命令行真的蓝瘦香菇.所幸17里集成了Git插件,用起来还是挺方便的. 1.本地安装git,工具还是要有的,主要用于配置环境,ssh配置一下.就不用每次都去连接了. ...

  3. Form的is_valid校验规则及验证顺序

    一.验证顺序   查看form下的源码了解顺序 BaseForm为基类,中间包含了is_valid校验方法 @html_safe class BaseForm: ......... self.is_b ...

  4. mysql_单表查询

    单表查询 比较符 当在子句中使用 <. >. <=. >=. <>或 !=时,字段的名字不加引号.如果使用引号,则查询出的结果为空,并且不会报错. ; 等号 当在子 ...

  5. MySQL 深入浅出数据库索引原理(转)

    本文转自:https://www.cnblogs.com/aspwebchh/p/6652855.html 前段时间,公司一个新上线的网站出现页面响应速度缓慢的问题, 一位负责这个项目的但并不是搞技术 ...

  6. Git使用过程中的问题

    Q-1:怎么切换到远程的分支 本地已经有一个代码库了(是从github上clone的),但是现在远程库中一个新的branch,怎么拉取远程分支,并在本地创建该分支(内容一样).how to do? # ...

  7. DDoS攻击、CC攻击的攻击方式和防御方法

    DDoS攻击.CC攻击的攻击方式和防御方法 - sochishun - 博客园https://www.cnblogs.com/sochishun/p/7081739.html cc攻击_百度百科htt ...

  8. 对B+树,B树,红黑树的理解

    出处:https://www.jianshu.com/p/86a1fd2d7406 写在前面,好像不同的教材对b树,b-树的定义不一样.我就不纠结这个到底是叫b-树还是b-树了. 如图所示,区别有以下 ...

  9. spark单击 搭建

    http://files.cnblogs.com/files/yxnyd/spark.zip

  10. HDU 5898 odd-even number

    题目:odd-even number 链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5898 题意:给一个条件,问l 到r 之间有多少满足条件的 ...