SP3734 PERIODNI - Periodni
题解:
第一道笛卡尔树dp
会发现以一个点为分界 如果左边大于它右边大于它 那么大于的那部分是相互不影响的
于是我们对序列建立笛卡尔树
满足父亲节点的v<儿子节点的v 然后这棵树的中序遍历为原序列
这样子我们就可以dp了
考虑一个矩形的方案数
$C(n,i)*C(m,i)*i!$ 其中$i!$表示行列自由匹配
然后现在的话我们只需要统计当前点包含的行数-用掉的 以及 列
另外处理逆元前缀积有一个比正着递推常数小的方法。。(少了取模和除法运算)
代码:
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
namespace IO{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T> void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; int Z,C1=-;
template<class T>void wer(T x)
{
if (x<) sr[++C1]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C1]=z[Z],--Z);
}
IL void wer1()
{
sr[++C1]=' ';
}
IL void wer2()
{
sr[++C1]='\n';
}
template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
template<class T>IL T MAX(T x,T y){return x>y?x:y;}
template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
using namespace IO;
const int N=;
const int N1=1e6+;
const int N2=1e6;
const int mo=1e9+;
int n,k,v[N],s[N],t,ls[N],rs[N];
int jc[N1],jc2[N1];
int dp[N][N],w[N];
ll tmp[N];
int ksm(int x,int y)
{
if (y==) return();
if (y==) return(x);
int k=ksm(x,y/);
k=1ll*k*k%mo;
if (y%==) k=1ll*k*x%mo;
return k;
}
int C(int x,int y)
{
if (x<y) return();
return 1ll*jc[x]*jc2[y]%mo*jc2[x-y]%mo;
}
void dfs(int x,int y)
{
w[x]=;
if (ls[x])
{
dfs(ls[x],v[x]); w[x]+=w[ls[x]];
}
if (rs[x])
{
dfs(rs[x],v[x]); w[x]+=w[rs[x]];
}
me(tmp);
rep(i,,w[x])
{
ll y=;
rep(j,,i)
y+=1ll*dp[ls[x]][j]*dp[rs[x]][i-j]%mo;
tmp[i]=y%mo;
}
rep(i,,w[x])
rep(j,,i)
(dp[x][i]+=1ll*tmp[j]*C(v[x]-y,i-j)%mo
*C(w[x]-j,i-j)%mo*jc[i-j]%mo)%=mo;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(k);
int rt;
rep(i,,n)
{
read(v[i]);
bool tt=;
while (v[i]<v[s[t]]) t--,tt=;
rs[s[t]]=i;
if (tt) ls[i]=s[t+];
s[++t]=i;
}
rt=rs[];
jc[]=; jc2[]=;
rep(i,,N2) jc[i]=1ll*jc[i-]*i%mo;
jc2[N2]=ksm(jc[N2],mo-);
dep(i,N2-,) jc2[i]=1ll*jc2[i+]*(i+)%mo;
dp[][]=;
dfs(rt,);
cout<<dp[rt][k]<<endl;
return ;
}
SP3734 PERIODNI - Periodni的更多相关文章
- 题解 SP3734 【PERIODNI - Periodni】
考虑用\(DP\)和组合数学来解决. 因为原图像不规则的形状不好处理,所以先用笛卡尔树(性质为小根堆)将其划分成一个一个的矩形. 发现在笛卡尔树上的每个节点都对应一个矩形,矩形高为\(h_x-h_{f ...
- [BZOJ2616]SPOJ PERIODNI 树形dp+组合数+逆元
2616: SPOJ PERIODNI Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 128 Solved: 48[Submit][Status][ ...
- 【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP
[BZOJ2616]SPOJ PERIODNI Description Input 第1行包括两个正整数N,K,表示了棋盘的列数和放的车数. 第2行包含N个正整数,表示了棋盘每列的高度. Output ...
- BZOJ.2616.SPOJ PERIODNI(笛卡尔树 树形DP)
BZOJ SPOJ 直观的想法是构建笛卡尔树(每次取最小值位置划分到两边),在树上DP,这样两个儿子的子树是互不影响的. 令\(f[i][j]\)表示第\(i\)个节点,放了\(j\)个车的方案数. ...
- BZOJ2616 SPOJ PERIODNI(笛卡尔树+树形dp)
考虑建一棵小根堆笛卡尔树,即每次在当前区间中找到最小值,以最小值为界分割区间,由当前最小值所在位置向两边区间最小值所在位置连边,递归建树.那么该笛卡尔树中的一棵子树对应序列的一个连续区间,且根的权值是 ...
- BZOJ2616 : SPOJ PERIODNI
长为$A$,宽为$B$的矩阵放$K$个车的方案数$=C(A,K)\times C(B,K)\times K!$. 建立笛卡尔树,那么左右儿子独立,设$f[i][j]$表示$i$子树内放$j$个车的方案 ...
- spoj periodni
题解: dp 方程弄出来就好做了 代码: #include<bits/stdc++.h> ,M=; typedef int arr[N]; typedef long long ll; in ...
- 解题:SPOJ 3734 Periodni
题面 按列高建立笛卡尔树,转成树上问题...... 笛卡尔树是什么? 它一般是针对序列建立的,是下标的BST和权值的堆(即中序遍历是原序列连续区间,节点权值满足堆性质),这里不讲具体怎么建树(放在知识 ...
- bzoj2616: SPOJ PERIODNI——笛卡尔树+DP
不连续的处理很麻烦 导致序列DP又找不到优秀的子问题 自底向上考虑? 建立小根堆笛卡尔树 每个点的意义是:高度是(自己-father)的横着的极大矩形 子问题具有递归的优秀性质 f[i][j]i为根子 ...
随机推荐
- 使用javascript调用com组件
<html> <head> <title> 调用com组件的方法示例 </title> <script language="javasc ...
- Java的if判断对象为null时,null放在比较运算符的左边还是右边较好?
如java中:if(name == null)和if(null == name)有什么讲究吗? 答:在java里面,它们是一样的.但是通常写为null == name.这其实是在C语言里面引申出来的. ...
- mysql生成数据字典
git clone https://github.com/twindb/undrop-for-innodb.git make [root@redis01 undrop-for-innodb]# mak ...
- Android下利用zbar类库实现扫一扫
程序源代码及可执行文件下载地址:http://files.cnblogs.com/rainboy2010/zbardemo.zip Android下常用的条码扫描类库有zxing和zbar,比较了一下 ...
- windows 2012执行powershell脚本报错
使用powershell运行脚本报错:进行数字签名.无法在当前系统上运行该脚本.有关运行脚本和设置执行策略的详细信息 修复方法:powershell "Set-ExecutionPolicy ...
- Python-mysql 权限 pymysql 注入共计
1.mysql用户管理 *** 数据安全非常重要 不可能随便分配root账户 应该按照不同开发岗位分配不同的账户和权限 mysql中 将于用户相关的数据放在mysql库 user - > db ...
- centos7_ linux : Nginx安装手册
一: nginx安装环境 1: oracle vm虚拟机+Centos7系统的yum环境的安装 配置本地yum库(用root用户操作) 创建挂载目录 mkdir /mnt/cdrom 查看挂载目录 l ...
- Confluence 6 使用页面请求属性来对慢性能进行问题解决
这个页面告诉你如何启用页面请求属性.当这个属性启用以后,你可以查看在 Confluence 任何页面完成的一个记录消耗的时间(毫秒).如果 Confluence 反应缓慢的话,一个关于慢页面请求的内部 ...
- Confluence 6 使用 Decorator 宏
Decorator 宏(Macros)是 Velocity 宏.这个宏可以被用来在页面编辑 Custom decorators 中创建复杂或者可变的部分,例如菜单,页面其他部分等.Decorator ...
- STL 容器区别:vector、list、deque、set、map的底层实现
https://blog.csdn.net/shawjan/article/details/45424405