[XSY] PQ树(区间DP)

PQ树

  • 对于非叶子节点,它只能调换它的儿子的顺序,却不能调换整颗子树的顺序
  • 合法的PQ树都能表示出1,2,3,…,n 这个排列
  • 由以上两点可以得出:PQ树的每棵子树对应的一定都是一段连续数字区间
  • 考虑区间DP,设f(l,r)f(l,r)f(l,r)表示数字l~r构成一棵PQ树的方案数
  • 数字l~r 能够构成一棵子树 当且仅当 数字l~r 在题目给出的所有排列中都在一段连续区间中,我们定义这样的 [l,r] 是“好的”
  • 若[l,r]不是"好的",f(l,r)=0f(l,r)=0f(l,r)=0
  • 若[l,r]是"好的",要算f(l,r)f(l,r)f(l,r),分 树根为P点 和 树根为Q点 两种情况讨论
  • 若树根为P点:f(l,r)+=∑i=lr−1f(l,i)g(i+1,r)f(l,r)+=\sum_{i=l}^{r-1}f(l,i)g(i+1,r)f(l,r)+=i=lr1f(l,i)g(i+1,r)(其中g(i+1,r)g(i+1,r)g(i+1,r)表示数字i+1~r构成一片PQ树森林(可以只有一颗树) 的方案数)
  • g(l,r)=f(l,r)+∑i=lr−1f(l,i)g(i+1,r)g(l,r)=f(l,r)+\sum_{i=l}^{r-1}f(l,i)g(i+1,r)g(l,r)=f(l,r)+i=lr1f(l,i)g(i+1,r)(注意这里并不要求[l,r]是“好的”)
  • 若树根为Q点:
    f(l,r)+=∑i=lr−1[在题目给出的排列中,数字i,i+1,r出现的位置均满足单调递增或递减]f(l,i)q(i+1,r)f(l,r)+=\sum_{i=l}^{r-1}[在题目给出的排列中,数字i,i+1,r出现的位置均满足单调递增或递减]f(l,i)q(i+1,r)f(l,r)+=i=lr1[i,i+1,r]f(l,i)q(i+1,r)
    q(i+1,r)q(i+1,r)q(i+1,r)表示数字i+1~r构成Q节点下除第一棵子树外的其它子树(至少2棵) 的方案数)

ps:因为数字i,i+1,r一定分属3棵子树,所以它们的位置关系可以代表其所在子树的位置关系

  • q(l,r)=∑i=lr−1f(l,i)(f(i+1,r)+[在题目给出的排列中,数字i,i+1,r出现的位置均满足单调递增或递减]q(i+1,r))q(l,r)=\sum_{i=l}^{r-1}f(l,i)(f(i+1,r)+[在题目给出的排列中,数字i,i+1,r出现的位置均满足单调递增或递减]q(i+1,r))q(l,r)=i=lr1f(l,i)(f(i+1,r)+[i,i+1,r]q(i+1,r))

ps:这里在实现上有一个小技巧:与其在dp时不断判断 数字i,i+1,r出现的位置是否满足单调递增或递减 ,我们在求q时就把这个条件加进去,即若 某排列中数字l-1l,l,r出现的位置不满足单调递增或递减,直接令q(l,r)=0q(l,r)=0q(l,r)=0

pps:关于转移式如何推出——其实我们计算f,g,qf,g,qf,g,q的基本方法都是枚举第一棵子树,然后讨论剩余子树的情况

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll; 
const int N=510;
const ll mod=1e9+7;
int K,n,a[N][N],pos[N][N],num[N][N];
bool ok[N][N];
ll f[N][N],g[N][N],q[N][N];
//f[l][r]:数l~r构成一棵PQ树的方案数
//g[l][r]:数l~r构成一片PQ树森林的方案数(可以只有一棵树)
//q[l][r]:数l~r构成Q节点下除第一棵子树外的其它子树 的方案数 
void pre(){for(int i=1;i<=K;i++){for(int j=1;j<=n;j++){int minn=a[i][j],maxn=a[i][j];for(int k=j;k<=n;k++){minn=min(minn,a[i][k]);maxn=max(maxn,a[i][k]);if(k-j==maxn-minn){//排列i中区间[j,k]里的数是连续的num[minn][maxn]++;//即区间[j,k]里的数在排列i中属于一段连续区间 } }}}for(int i=1;i<=n;i++)for(int j=i;j<=n;j++)ok[i][j]=(num[i][j]==K);
}
ll F(int l,int r);
ll G(int l,int r);
ll Q(int l,int r);
ll F(int l,int r){if(!ok[l][r]) return 0;if(l==r) return 1;if(f[l][r]!=-1) return f[l][r];f[l][r]=0;for(int i=l;i<r;i++){f[l][r]=(f[l][r]+F(l,i)*G(i+1,r)%mod)%mod;//树根是P节点 f[l][r]=(f[l][r]+F(l,i)*Q(i+1,r)%mod)%mod;//树根是Q节点 }return f[l][r];
}
ll G(int l,int r){if(l>r) return 0;if(l==r) return 1;if(g[l][r]!=-1) return g[l][r];g[l][r]=F(l,r);for(int i=l;i<r;i++){g[l][r]=(g[l][r]+F(l,i)*G(i+1,r)%mod)%mod;}return g[l][r];
}
ll Q(int l,int r){if(l>=r) return 0;if(q[l][r]!=-1) return q[l][r];for(int i=1;i<=K;i++){if((pos[i][l-1]<pos[i][l])^(pos[i][l]<pos[i][r])){q[l][r]=0;return 0;}}q[l][r]=0;for(int i=l;i<r;i++){q[l][r]=(q[l][r]+F(l,i)*((Q(i+1,r)+F(i+1,r))%mod)%mod)%mod;}return q[l][r];
}
int main(){scanf("%d%d",&K,&n);for(int i=1;i<=K;i++){for(int j=1;j<=n;j++){scanf("%d",&a[i][j]);pos[i][a[i][j]]=j;}}pre();memset(f,-1,sizeof(f));memset(g,-1,sizeof(g));memset(q,-1,sizeof(q));printf("%d\n",F(1,n));return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客网 【每日一题】5月14日题目 maze

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld题目描述 小明来到一个由n x m个格子组成的迷宫&#xff0c;有些格子是陷阱&#xff0c;用’#‘表示&#xff0c;小明…

你需要知道的这几种 asp.net core 修改默认端口的方式

一般情况下&#xff0c;aspnetcore发布后的默认端口是5000&#xff0c;这个大家都知道&#xff0c;而且默认骨架代码中没有看到任何让你输入的ip地址和端口号&#xff0c;但作为程序员的我们&#xff0c;不希望被框架所管制&#xff0c;那如何实现默认端口的修改呢&#xff1f;…

CF1139D-Steps to One【期望dp,莫比乌斯反演】

正题 题目链接:https://www.luogu.com.cn/problem/CF1139D 题目大意 不停的在表格中填下1∼m1\sim m1∼m中随机一个数&#xff0c;直到所有数的gcd1gcd1gcd1为止&#xff0c;求期望数的个数。 解题思路 设fnf_nfn​表示现在gcdgcdgcd为nnn时的期望个数。那么有转移方程fn∑i…

【DP】错排问题(ybtoj DP-1-1)

错排问题 ybtoj DP-1-1 题目大意 求n个数的错排种数 输入样例 2输出样例 1数据范围 1⩽n⩽201\leqslant n \leqslant 201⩽n⩽20 解题思路 设fif_ifi​为i个数的错排种数 考虑第i个数能放在前面i-1个位置的其中一个&#xff08;i-1种选法&#xff0c;要乘i-1&#xff0…

牛客网【每日一题】5月15日题目 储物点的距离

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 一个数轴&#xff0c;每一个储物点会有一些东西&#x…

[XSY] 最长公共子串对(后缀自动机)

最长公共子串对 先放一段考场暴力代码&#xff1a; #include<iostream> #include<cstdio> #include<cstring> using namespace std; char a[2005],b[2005]; int na,nb,f[2005][2005],c[2005][2005],ans; //f[i][j]表示 s[1...i]与 t[1...j]以s[i]、t[j]结尾…

P3911-最小公倍数之和【莫比乌斯反演】

正题 题目链接:https://www.luogu.com.cn/problem/P3911 题目大意 给出数列AAA求∑i1n∑j1nlcm(Ai,Aj)\sum_{i1}^n\sum_{j1}^nlcm(A_i,A_j)i1∑n​j1∑n​lcm(Ai​,Aj​) 解题思路 设cic_ici​表示AjiA_jiAj​i的个数&#xff0c;然后答案就是&#xff08;下面n5e4n5e4n5e4&…

【DP】奇怪汉诺塔(ybtoj DP-1-2)

奇怪汉诺塔 ybtoj DP-1-2 题目大意 求四根柱子的汉诺塔问题 输出 共12行 每行输出第一根柱子有i个圆盘的最小步数 解题思路 设aia_iai​表示三根柱子&#xff0c;第一根柱子有i个圆盘的步数 很显然是先移i-1个到第二根&#xff0c;再移最大的到第三根&#xff0c;再把i-…

牛客网【每日一题】5月18日 「土」秘法地震

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 帕秋莉掌握了一种土属性魔法 这种魔法可以在一片kk大小…

AspNetCore 中使用 InentityServer4(2)

基于上一篇文章 实现对IdnetityServer4 服务的使用1&#xff1a;添加接口解决方案&#xff0c;并且使接口受认证服务的保护&#xff1a;首先在解决方案中添加Api项目如下图所示&#xff1a;在API项目中添加Nuget 引用 如下图所示&#xff1a;Install-Package IdentityServer4.A…

[XSY] 宝藏(LCS,DP)

宝藏 首先&#xff0c;这个问题等价于给定两个字符串S,T &#xff0c;每次询问LCS(S[1,n],T[x,y])LCS(S[1,n],T[x,y])LCS(S[1,n],T[x,y])。 对每个询问重新求一遍LCSLCSLCS显然不现实&#xff0c;又因为yyy都是连续变化的&#xff0c;我们考虑探讨 LCS(S[1,n],T[x,y])与LCS(S[…

【DP】数的划分(ybtoj DP-1-3)

数的划分 ybtoj DP-1-1 题目大意 给你一个n&#xff0c;让你分成k份&#xff0c;问有多少种分法&#xff08;1,2和2,1为同一种&#xff09; 输入样例 7 3输出样例 4 样例解释 四种分法为&#xff1a;1,1,5;1,2,4;1,3,3;2,2,3.1,1,5; \ \ 1,2,4; \ \ 1,3,3; \ \ 2,2,3.1…

CF570D-Tree Requests【长链剖分】

正题 题目链接:https://www.luogu.com.cn/problem/CF570D 题目大意 nnn个点的一棵树&#xff0c;每个节点有字母&#xff0c;每次询问一个节点xxx的子树中深度为kkk的所有点的字母能否经过重排构成一个回文串。 解题思路 首先把每个字母的奇偶状压一下 然后方法比较多&#x…

牛客网 【每日一题】5月13日 加分二叉树

试题链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 设一个n个节点的二叉树tree的中序遍历为&#xff0…

Visual Studio 2017 15.8概览

Microsoft正式发布VS2017的第八次更新&#xff0c;即15.8。15.8提供了今年夏天预览的大量新特性&#xff0c;包括Code Cleanup、IDE支持多重查补&#xff08;Multiple Caret&#xff09;、Visual Studio Code和ReSharper快捷键设置等。各类开发人员均可受益于这些已供使用的新特…

[XSY] 简单的数论题(数学、构造)

简单的数论题 m(a3b3)n(c3d3)m(a^3b^3)n(c^3d^3)m(a3b3)n(c3d3) 考虑因式分解(a3b3),(c3d3):考虑因式分解(a^3b^3),(c^3d^3):考虑因式分解(a3b3),(c3d3): a3b3(ab)3−3ab(ab)(ab)(a2b2−ab)a^3b^3(ab)^3-3ab(ab)(ab)(a^2b^2-ab)a3b3(ab)3−3ab(ab)(ab)(a2b2−ab) c3d3(cd)3−3c…

P4322-[JSOI2016]最佳团体【0/1分数规划,树形背包】

正题 题目链接:https://www.luogu.com.cn/problem/P4322 题目大意 nnn个点的一棵树&#xff0c;每个节点有一个(si,pi)(s_i,p_i)(si​,pi​)&#xff0c;选择一个点必须选择它的父节点&#xff0c;求选择KKK个点使得∑pxi∑sxi\frac{\sum p_{x_i}}{\sum s_{x_i}}∑sxi​​∑px…

【DP】平铺方案(ybtoj DP-1-5)

平铺方案 ybtoj DP-1-5 题目大意 求用121\times 212和222\times 222的瓦片平铺2n2\times n2n矩形的方案数 输入样例 2 8 12 100 200输出样例 3 171 2731 845100400152152934331135470251 1071292029505993517027974728227441735014801995855195223534251数据范围 0⩽n⩽2…

白兔的字符串

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 白兔有一个字符串T。白云有若干个字符串S1,S2…Sn。 白…

利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop

Aop即是面向切面编程&#xff0c;众多Aop框架里Castle是最为人所知的&#xff0c;另外还有死去的Spring.NET&#xff0c;当然&#xff0c;.NET Core社区新秀AspectCore在性能与功能上都非常优秀&#xff0c;已经逐渐被社区推崇和有越来越多的人使用。感谢柠檬同学的礼物&#x…