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为根子 ...
随机推荐
- 题解-PKUWC2018 Slay the Spire
Problem loj2538 Solution 在考场上当然要学会写暴力,考虑如果手上已经有了\(a\)张攻击牌和\(b\)张强化牌: 首先强化牌会在攻击牌之前用(废话),其次要将两种牌分别从大往小 ...
- UPS不间断电源工作原理简述
原文地址:https://blog.csdn.net/uamix/article/details/52776297 一.定义 UPS即不间断电源,是将蓄电池(多为铅酸免维护蓄电池)与主机相连接,通过主 ...
- jquery获取、设置、删除cookie
获取cookie: function getCookie(cname) { var name = cname + "="; var ca = document.cookie.spl ...
- GIT入门文档
集中式(SVN): 集中式版本控制系统,版本库是集中存放在中央服务器的,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器. 集中式版本控制系 ...
- Linux Free命令每个数字的含义 和 cache 、buffer的区别
Linux Free命令每个数字的含义 和 cache .buffer的区别 我们按照图中来一细细研读(数字编号和图对应)1,total:物理内存实际总量2,used:这块千万注意,这里可不是实际已经 ...
- Light OJ 1214
简单大数模拟题: #include<bits/stdc++.h> using namespace std; typedef long long ll; string Num; vector ...
- mysql设计表时注意事项
说明:本文是对项目过程中的一些要求的简单汇总整理,主要是供个人本身参考... 一.表设计 1. 在创建表结构时,表名.字段需要见名知意,不采用拼音 create table `tb_abc` ( ...
- 【原创】大数据基础之Flume(2)kudu sink
kudu中的flume sink代码路径: https://github.com/apache/kudu/tree/master/java/kudu-flume-sink kudu-flume-sin ...
- orm分组,聚合查询,执行原生sql语句
from django.db.models import Avg from app01 import models annotate:(聚合查询) ret=models.Article.objects ...
- 2)实现github自动登陆获取信息
# -*- coding:utf-8 -*- # __author__ = 'lixiang' # 实现github自动登陆和获取数据 import requests from bs4 import ...