【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 ...
随机推荐
- 面试题之C# 内存管理与垃圾回收
面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...
- letter combinations of a phone number(回溯)
Given a digit string, return all possible letter combinations that the number could represent. A map ...
- PLSQL学习教程(全)
基于ORACLE9i+PL/SQLDeveloper7.1.4) 课程 一 PL/SQL 基本查询与排序 本课重点: 1.写SELECT语句进行数据库查询 2.进行数学运算 3.处理空值 4.使用别名 ...
- dp,px,pt,sp 的区别 以及dp 和 px 互转
dp = dip : device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不 ...
- Python自学编程开发路线图(文中有免费资源)
Python核心编程 免费视频资源<Python入门教程>:http://yun.itheima.com/course/145.html Python 基础学习大纲 所处阶段 主讲内容 技 ...
- Niop2017初赛滚粗记
初赛踢蹬滚粗 TOT (╯°Д°)╯︵┻━┻ ヽ(`Д´)ノ︵ ┻━┻ ┻━┻ 排序啊排序,净是排序,自打我学了C++就再没学过排序!!wtf! (╯°Д°)╯︵ /(.□ . )我tm怎么知道建国那 ...
- 架构之Nginx(负载均衡/反向代理)
Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器 ,也是一个 IMAP/POP3/SMTP 代理 服务器 . Nginx 是由 Igor Sys ...
- java后台服务器实现极光推送
一.添加极光推送所需要的jar包,项目使用的maven,所以只需要在pom文件里添加jar包依赖 <dependency> <groupId>cn.jpush.api</ ...
- Python之命名空间、闭包、装饰器
一.命名空间 1. 命名空间 命名空间是一个字典,key是变量名(包括函数.模块.变量等),value是变量的值. 2. 命名空间的种类和查找顺序 - 局部命名空间:当前函数 - 全局命名空间:当前模 ...
- Robot Framework之测试用例分层实战
1.1 测试用例的第一层(交互层) 1. 创建项目资源(Resource). 操作步骤: 点”项目名称”->右键,选New Resource,在弹窗Name 输入框输入资源名称 mykeywo ...