Problem Statement

Find the number of the possible tuples of sequences (A0,A1,…,AN) that satisfy all of the following conditions, modulo M:

  • For every i (0≤iN)Ai is a sequence of length i consisting of integers between 1 and K (inclusive);
  • For every i (1≤iN)Ai−1 is a subsequence of Ai, that is, there exists1≤xii such that the removal of the xi-th element of Ai would result in a sequence equal to Ai−1;
  • For every i (1≤iN)Ai is lexicographically larger than Ai−1.

Constraints

  • 1≤N,K≤300
  • 2≤M≤109
  • NK and M are integers.

Input

Input is given from Standard Input in the following format:

N K M

Output

Print the number of the possible tuples of sequences (A0,A1,…,AN), modulo M.

Sample Input 1

2 2 100

Sample Output 1

5

Five tuples below satisfy the conditions:

  • (),(1),(1,1)
  • (),(1),(1,2)
  • (),(1),(2,1)
  • (),(2),(2,1)
  • (),(2),(2,2)

Sample Input 2

4 3 999999999

Sample Output 2

358

Sample Input 3

150 150 998244353

Sample Output 3

186248260

    最近的一场AGC的题目(1200分题!!),当时比赛的时候一直怼这个题没怼出来QWQ,之后只做了前三个题QWQ(这样也能涨rating???),后来回想了一下,搞了半天才搞出来。
因为这个题目实在是不错,所以我会尽力写好完整的题解的hhhh 第一部分:模型构建。
稍微想想就可以知道,第i行肯定是在第i-1行的基础上再插入一个数字得来的,并且要求字典序更大。
但是稍不留神就会算重,比如 在 1,3,3,2 的两个3后面插入3,得到的新的序列是一样的。
那么在不考虑容斥的情况下,我们如何去构造出 不重复 且满足字典序更大 的计算方案呢? 考虑 a[i][] 和 a[i-1][] 第一个不一样的位置j (为了方便视 a[i-1][i] = 0),显然a[i][j] > a[i-1][j],不然字典序就更小了。
并且很容易想到,如果两个 a[i][] 的 j不一样,那么它们肯定是不同的,所以我们现在就找到了一种不会算重的方案。 我们接着转化模型,设j是最小的满足 a[i][k] != a[i-1][k] 的k,那么我们可以把第i次操作看成 在a[i-1][j] 前面挂了一个新的数 a[i][j] (要求 a[i][j] > a[i-1][j]),从而使a[i-1][j] 位移到了 a[i][j+1]。
于是我们就可以把第i次操作加入的点 抽象成一棵节点带权的有根树的节点(初始只有0节点,且权值是0),一次操作就相当于在某一个节点下挂一个新的权值大于它的节点(对应在原序列某个数前面挂数)。
问题就转化成了,问有多少颗节点数为 n+1 的有根树,儿子的编号都小于爸爸,权值都大于爸爸,并且根的权值是0(对应第一次操作可以加入任意[1,k]的数)。 第二部分:高效求解问题。
不难想到设 f[i][j] 为 有i个节点,且根的权值是j的有根树的方案数,但是转移不是很好想的样子。。。
我们先钦定这棵树内的节点编号是1~i,那么转移就可以写成: f[i][j] = ∑ C(i-2,u-1) * f[u][k] * f[i-u][j] (k>j)
这就相当于枚举,和2节点在一颗子树内的分别是哪些点,这颗子树的方案和剩下的点的方案(依然是以1为根,只不过节点数变成了i-u)。
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=305;
int n,k,m,f[maxn][maxn],C[maxn][maxn],g[maxn][maxn];
inline int add(int x,int y){ x+=y; return x>=m?x-m:x;}
inline void ADD(int &x,int y){ x+=y; if(x>=m) x-=m;} inline void solve(){
const int ha=m; C[0][0]=1;
for(int i=1;i<=n;i++){
C[i][0]=1;
for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
} fill(g[0],g[0]+k+1,1);
for(int i=0;i<=k;i++) g[1][i]=k-i+1,f[1][i]=1; for(int i=2;i<=n;i++){
// calc f[i][] for(int j=0;j<=k;j++)
for(int u=1;u<i;u++) ADD(f[i][j],C[i-2][u-1]*(ll)g[u][j+1]%ha*(ll)f[i-u][j]%ha); // prepare prefix sum for(int j=k;j>=0;j--) g[i][j]=add(f[i][j],g[i][j+1]);
}
} int main(){
scanf("%d%d%d",&n,&k,&m),n++;
solve(),printf("%d\n",f[n][0]);
return 0;
}

  

 

AtCoder - 3962 Sequence Growing Hard的更多相关文章

  1. Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)

    题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...

  2. [AtCoder Grand Contest 024 Problem E]Sequence Growing Hard

    题目大意:考虑 N +1 个数组 {A0,A1,…,AN}.其中 Ai 的长度是 i,Ai 内的所有数字都在 1 到 K 之间. Ai−1 是 Ai 的子序列,即 Ai 删一个数字可以得到 Ai−1. ...

  3. AGC024E Sequence Growing Hard

    题意 给出\(n\),\(m\),\(mu\),问有多少个序列组\((A_0,A_1,\dots,A_n)\)满足: 序列\(Ai\)的长度恰好为\(i\) 所有元素均在\([1,m]\) \(A_{ ...

  4. AGC024C Sequence Growing Easy

    题目大意 你开始有一个序列x 它所有项都是0 你有一个操作:x[i]=x[i-1]+1 问你至少几次操作可以让x序列变为给定的a序列 分析 老年人完全不会这种脑子题/kk........ 我们定义b[ ...

  5. 【AtCoder】AGC024

    A - Fairness 如果奇数次是b - a 否则是a - b #include <bits/stdc++.h> #define fi first #define se second ...

  6. AtCoder Regular Contest 074 E:RGB Sequence

    题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_c 题目翻译 给你一行\(n\)个格子,你需要给每个格子填红绿蓝三色之一,并且同时满足\(m\ ...

  7. AtCoder Grand Contest 003 E - Sequential operations on Sequence

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...

  8. Atcoder E - RGB Sequence(dp)

    题目链接:http://arc074.contest.atcoder.jp/tasks/arc074_c 题意:一共有3种颜色,红色,绿色,蓝色.给出m个要求l,r,x表示在区间[l,r]内要有x种不 ...

  9. AtCoder AGC031D A Sequence of Permutations (群论、置换快速幂)

    题目链接 https://atcoder.jp/contests/agc031/tasks/agc031_d 题解 这居然真的是个找规律神题... 首先要明白置换的一些基本定义,置换\(p\)和\(q ...

随机推荐

  1. RAID介绍和实现

    RAID的全称是廉价磁盘冗余阵列(Redundant Array of Inexpensive Disks),于1987年由美国Berkeley 大学的两名工程师提出的. RAID出现的,最初目的是将 ...

  2. 1004 Counting Leaves (30 分)(树的遍历)

    给出一棵树,问每一层各有多少叶子节点 dfs遍历树 #include<bits/stdc++.h> using namespace std; vector<]; int n,m; i ...

  3. css深入理解vertical-align

    第一讲:vertical-align家族基本认识 了解vertical-align支持的属性值以及组成 属性: 1.inherit 2.线类 baseline,top,middle,bottom 3. ...

  4. maven学习(十六)——使用Maven构建多模块项目

    在平时的Javaweb项目开发中为了便于后期的维护,我们一般会进行分层开发,最常见的就是分为domain(域模型层).dao(数据库访问层).service(业务逻辑层).web(表现层),这样分层之 ...

  5. servlet 图片流

    http://www.cnblogs.com/focusj/archive/2011/04/30/2057577.html https://segmentfault.com/q/10100000004 ...

  6. kindeditor编辑器获取不到修改后的新文本

    在编辑文章的功能中,文章内容使用了kindeditor编辑器进行处理,但是修改文本后保存时发现获取到的内容还是修改前的文本内容. 引用编辑器的标签: <textarea id="txt ...

  7. gulp (转)

    “1. 我为什么使用grunt: 2. 我为何放弃grunt转投gulp: 3. 我为何放弃gulp与grunt,转投npm scripts: 4. 我为何放弃前端” —— 司徒正美 前端(段子)界的 ...

  8. ACMUniversity

    描述 在大学里,很多单词都是一词多义,偶尔在文章里还要用引申义.这困扰Redraiment很长的时间. 他开始搜集那些单词的所有意义.他发现了一些规律,例如 “a”能用“e”来代替, “c”能用“f” ...

  9. DP———4.完全背包问题(容量为V的背包可装最大价值的问题)

    Piggy-Bank Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  10. Android控件介绍

    1. 介绍 Android控件大多位于android.widget, android.view.View为他们的父类对于Dialog系列, android.app.Dialog为父类 Android的 ...