AtCoder - 3962 Sequence Growing Hard
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≤i≤N), Ai is a sequence of length i consisting of integers between 1 and K (inclusive);
- For every i (1≤i≤N), Ai−1 is a subsequence of Ai, that is, there exists1≤xi≤i such that the removal of the xi-th element of Ai would result in a sequence equal to Ai−1;
- For every i (1≤i≤N), Ai is lexicographically larger than Ai−1.
Constraints
- 1≤N,K≤300
- 2≤M≤109
- N, K 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的更多相关文章
- Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)
题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...
- [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. ...
- AGC024E Sequence Growing Hard
题意 给出\(n\),\(m\),\(mu\),问有多少个序列组\((A_0,A_1,\dots,A_n)\)满足: 序列\(Ai\)的长度恰好为\(i\) 所有元素均在\([1,m]\) \(A_{ ...
- AGC024C Sequence Growing Easy
题目大意 你开始有一个序列x 它所有项都是0 你有一个操作:x[i]=x[i-1]+1 问你至少几次操作可以让x序列变为给定的a序列 分析 老年人完全不会这种脑子题/kk........ 我们定义b[ ...
- 【AtCoder】AGC024
A - Fairness 如果奇数次是b - a 否则是a - b #include <bits/stdc++.h> #define fi first #define se second ...
- AtCoder Regular Contest 074 E:RGB Sequence
题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_c 题目翻译 给你一行\(n\)个格子,你需要给每个格子填红绿蓝三色之一,并且同时满足\(m\ ...
- AtCoder Grand Contest 003 E - Sequential operations on Sequence
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...
- Atcoder E - RGB Sequence(dp)
题目链接:http://arc074.contest.atcoder.jp/tasks/arc074_c 题意:一共有3种颜色,红色,绿色,蓝色.给出m个要求l,r,x表示在区间[l,r]内要有x种不 ...
- AtCoder AGC031D A Sequence of Permutations (群论、置换快速幂)
题目链接 https://atcoder.jp/contests/agc031/tasks/agc031_d 题解 这居然真的是个找规律神题... 首先要明白置换的一些基本定义,置换\(p\)和\(q ...
随机推荐
- Python全栈工程师
ParisGabriel Python 入门基础 print(“hello world”)变量 : 存储信息的,日后被调用.修改操作常量: 固定不变的量,字母大写命名规则:1. 字母数 ...
- 华东交通大学2017年ACM双基程序设计大赛题解
简单题 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submissio ...
- 【bzoj2959】长跑 LCT+并查集
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...
- 【距离GDKOI:44天&GDOI:107天】【BZOJ1040】[ZJOI2008] 骑士 (环套树DP)
其实已经准备退役了,但GDOI之前还是会继续学下去的!!当成兴趣在学,已经对竞赛失去信心了的样子,我还是回去跪跪文化课吧QAQ 第一道环套树DP...其实思想挺简单的,就把环拆开,分类处理.若拆成开的 ...
- Codeforces Round #324 (Div. 2) B
B. Kolya and Tanya time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- POJ2175:Evacuation Plan(消负圈)
Evacuation Plan Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 5665Accepted: 1481Special J ...
- 牛客小白月赛4——H-相邻的糖果
链接:https://www.nowcoder.com/acm/contest/134/H来源:牛客网 题目描述 有n个盒子摆成一排,每个盒子内都有ai个糖果. 现在你可以执行以下操作: ·你可以选择 ...
- js,将日期时分秒等格式化和转化
1.将js Date对象格式化为指定格式,添加一个原型方法 /** * 返回指定format的string * format eg:'yyyy-MM-dd hh:mm:ss' **/ Date.pro ...
- 汕头市队赛 SRM10 T3 数学上来先打表
数学上来先打表 SRM 10 描述 给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:1.每条边连接两个不同的点,每两个点之间至多有一条边2.不存在三个点a,b,c使三个点间两两 ...
- 百度经验:Win10查看已存储WiFi密码的两种方法
方法一:网络和共享中心查询 具体步骤可以参考:Win10查看WIFI密码的方法 方法二:命令提示符查询 1.右键单击开始按钮,选择“命令提示符(管理员)” 2.输入如下命令(下图①号命令): nets ...