【LOJ #6094. 「Codeforces Round #418」归乡迷途】
题目大意:
传送门。
lca说的很明白就不重复了。
题解:
先膜一发lca。
大体读完题以后我们可以知道对于第i个节点最短路一定是连向1到i-1中的某个点。
然后我们考虑将到1距离(这里及以下均是最短路)相等的点放到同一层,显然最后的总体结构应该是一棵树,再加上在同一层/深度相同的点之间连接一些边的并。
很容易发现一层的转移只需要知道上一层度数为2/3的个数,以及当前层之间的相互连接。
先说一下$n^5$做法。
设$f_{i,p1,p2,u_1,u_2}$表示插入第i个点时,上一层度数为2/3还剩$p1/p2$,这一层度数为2/3还剩$u1/u2$,很显然这个dp转移是比较好(e)想(xin)的……
这里就不写了……
然后是lca大神的$n^3$。
我们发现在事实上,我们并不需要在向上连边的同时和同层的连边,我们只需要在把这一层向上连边结束后计算一下当前层状态到最后连边状态的方案即可。
设$f_{i,j}$表示前i个点中,最后j个点为最后1层,且前i-j个点度数已经满足要求,但最后j个点只考虑向上一层如何连边。
设$g_{i,j,k}$来表示新的一层插了i个的情况下,上一层有j个点度数为2,k个点度数为3。
所有有$f_{i,j}=\sum_k f_{i-j,k}*g_{j,c0,c1}$。其中c0/1表示上一层要求度数为2/3的个数。
假设我们知道了$g$那么这个DP就是$n^3$。
1.显然$g_{0,0,0}=1$。
2.考虑$g$当新的一层没有节点时,即$i==0$,显然此时状态含义为当前层最后有度数2的点为$j$,3的点为$k$的方案数。此时,当$j==0$时,因为不会有度数为2的点,所以这次一定是一堆仍未在同层连接的点和最后一个添加点连成一个环。由于我们此时需要知道这个环的大小,所以我们得到:
$g_{0,0,k}=\sum_{l=2}^{k-1}g_{0,0,k-l-1}C_{k-1}^lN_{l+1}$。
这个表示最后状态里有$k$个三个度数的点由$k-l-1$个点的递推。(应该很好理解)
$N_i$表示项链数,$i>=2$,即圆排列除以2。
3.考虑当$j!=0$时,我们最终状态可以由$g_{0,j-2/j,k/k-1}$递推而来,当我们这次选择连接一个实际度数为1的点时,我们会产生两个度数为2的点,当选择实际度数为2的点时,我们会得到的一个度数为3和一个度数为2的点同时失去一个度数为2的点。同时由于之前选取集合的不同,此时我们得到:
$g_{0,j,k}=(j-1)g_{0,j-2,k}+k*g_{0,j,k-1}$。
4.当$i!=0$时,此时$g$回归本来含义。我们很轻易地得出此时DP方程:
$g_{i,j,k}=j*g_{i-1,j-1,k}+k*g_{i-1,j+1,k-1}$
至此问题解决了。Orz lca大神犇。
代码:
#include "bits/stdc++.h"
using namespace std;
inline int read() {
int s=,k=;char ch=getchar();
while (ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while (ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
}
const int N=,mod=1e9+;
typedef long long ll;
int n,d[N];
int f[N][N],g[N][N][N],fac[N],inv[N];
#define C(a,b) (1ll*fac[a]*inv[b]%mod*inv[a-b]%mod)
inline void init() {
int i,j,k,s;
fac[]=inv[]=;
inv[]=;
for (i=;i<=n;++i) inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
for (i=;i<=n;++i) fac[i]=1ll*fac[i-]*i%mod;
for (i=;i<=n;++i) inv[i]=1ll*inv[i-]*inv[i]%mod;
g[][][]=;
for (i=;i<=n;++i)
for (j=;j<=n-i;++j) if(i||j){
if (!i){
for (k=;k<j;++k)g[][i][j]=(g[][i][j]+C(j-,k)*g[][i][j-k-]%mod*fac[k]%mod*inv[])%mod;
}else {
if(i>=)g[][i][j]=(g[][i][j]+(i-1ll)*g[][i-][j])%mod;
if(j>=)g[][i][j]=(g[][i][j]+(ll)j*g[][i-][j-])%mod;
}
}
for (i=;i<n;++i)
for (s=;s<n-i;++s)
for (k=;k<=s;++k) {
j=s-k;
if (j) g[i][j][k]=(g[i][j][k]+(ll)j*g[i-][j-][k])%mod;
if (k) g[i][j][k]=(g[i][j][k]+(ll)k*g[i-][j+][k-])%mod;
}
}
int main(){
n=read();
register int i,j,k;
int c[];
for (i=;i<=n;++i) d[i]=read();
init();
f[d[]+][d[]]=;
for (i=d[]+;i<=n;++i)
for (j=;j<=i-d[]-;++j) {
c[]=c[]=;
for (k=;k<i-j;++k) {
++c[d[i-j-k+]==];
f[i][j]=(f[i][j]+(ll)g[j][c[]][c[]]*f[i-j][k])%mod;
}
}
int ans=;
c[]=c[]=;
for (i=;i<n;++i) {
++c[d[n-i+]==];
ans=(ans+(ll)f[n][i]*g[][c[]][c[]])%mod;
}
printf("%d\n",ans);
}
人家没有抄代码辣233
【LOJ #6094. 「Codeforces Round #418」归乡迷途】的更多相关文章
- [LOJ#531]「LibreOJ β Round #5」游戏
[LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...
- [LOJ#530]「LibreOJ β Round #5」最小倍数
[LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...
- [LOJ#516]「LibreOJ β Round #2」DP 一般看规律
[LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...
- [LOJ#515]「LibreOJ β Round #2」贪心只能过样例
[LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...
- [LOJ#525]「LibreOJ β Round #4」多项式
[LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...
- [LOJ#526]「LibreOJ β Round #4」子集
[LOJ#526]「LibreOJ β Round #4」子集 试题描述 qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两 ...
- [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)
[LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...
- loj #547. 「LibreOJ β Round #7」匹配字符串
#547. 「LibreOJ β Round #7」匹配字符串 题目描述 对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的任意一个长度为 ...
- loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分
$ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...
随机推荐
- CSS3概述
首先我们了解下什么是css3,css3是css技术的一个升级.css3中并没有采用总体结构,而是采用分工协作的模块化结构. css3中的模块 模块名称 功能描述 basic box model 定义各 ...
- 移动端 slide拖拽
<html> <head> <meta charset="UTF-8"> <meta name="viewport" ...
- OO开发思想:面向对象的开发方法(Object oriented,OO)
面向对象的开发方法(Object oriented,OO)认为是好文章吧,拿来分享一下(转载) 面向对象的开发方法(Object oriented,OO) 从事软件开发的工程 师们常常有这样 的体会: ...
- 在VirtualBox中的Ubuntu中添加新硬盘
步骤如下: 1. 关闭Ubuntu系统,打开VistualBox,"设置"->"存储"->"添加虚拟硬盘" 2. 启动Ubunt ...
- python3学习笔记1---引用http://python3-cookbook.readthedocs.io/zh_CN/latest/
2018-02-28数据结构和算法(1) 1.1解压序列赋值给多个变量: 任何的序列(或者是可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量. 唯一的前提就是变量的数量必须跟序列元素的数量是 ...
- ubuntu 18.04安装docker以及docker内配置neo4j
如题 切换到root用户下 apt install docker.io 等啊等,很快,就好了.. 如图 即可使用 如果出现Cannot connect to the Docker daemon at ...
- 你需要知道的Android拍照适配方案
拍照功能实现 Android 程序上实现拍照功能的方式分为两种:第一种是利用相机的 API 来自定义相机,第二种是利用 Intent 调用系统指定的相机拍照.下面讲的内容都是针对第二种实现方式的适配. ...
- linux系统下安装tomcat服务器
一.首先需要关闭linux防火墙(重启后生效) chkconfig iptables off 二.从官网上下载Linux合适版本的tomcat,我现在下来的文件为apache-tomcat-8.5.3 ...
- Oracle数据库逻辑迁移之数据泵的注意事项
环境:数据迁移,版本 11.2.0.4 -> 12.2.0.1 思考: 对于DBA而言,常用物理方式的迁移,物理迁移的优势不必多说,使用这种方式不必担心对象前后不一致的情况,而这往往也解决了不懂 ...
- esayui扩展验证方法
下面是关于平时中积累的esayui扩展验证方法仅作记录: /**************************************************************** ...