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为根子 ...
随机推荐
- linux中bashrc与profile的区别
bashrc与profile的区别 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shell 和non-login shell. ...
- 题解-Atcoder_agc005D ~K Perm Counting
Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\( ...
- 【原创】大叔经验分享(39)spark cache unpersist级联操作
问题:spark中如果有两个DataFrame(或者DataSet),DataFrameA依赖DataFrameB,并且两个DataFrame都进行了cache,将DataFrameB unpersi ...
- 使用PHP Manager for IIS时,Windws 10自带IIS注意事项
1)开启IIS 10:在“控制面板”的“程序和功能”的“启用或关闭Windows功能”内,勾选(启用)“Internet Information Services”,然后确定,进行安装. 2)若要使用 ...
- Docker架构图
Docker架构图 服务器---主机系统中通过Cgroup和Namespace-----------划分成多个bins/libs---------------每个app运行在独立的bins/libs中 ...
- Android gradle provided、implementation等指令注意点
其实这类文章博客网上一搜一大堆,但有些地方可能说的不太清楚(都一样的内容,抄袭太严重),这里只是做个精简的总结和一些其他地方没提到的点. 一.Android Studio 3.0开始使用了新的指令,原 ...
- 移动端判断ios还是android终端
<script> //判断ios还是android终端 var u = navigator.userAgent; var isAndroid = u.indexOf ...
- Confluence 6 重新获得附件指南
每一个文件在恢复上传到 Confluence 的时候必须单独重命名,你可以通过下面说明的 3 个方法中选择一个进行操作: 选择 A - 通过文件名恢复附件 如果你知道你需要恢复的每一个文件名,尤其是你 ...
- Confluence 6 workbox 通知包含了什么
当一个用户在 Confluence 中进行下面的操作的时候,workbox 将会显示为通知: 分享(Shares)你的页面或者博客页面. 提及(Mentions)你的页面,博客页面,回复或者任务. 你 ...
- python之属性描述符与属性查找规则
描述符 import numbers class IntgerField: def __get__(self, isinstance, owner): print('获取age') return se ...