题目大意:

  传送门

  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」归乡迷途】的更多相关文章

  1. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  2. [LOJ#530]「LibreOJ β Round #5」最小倍数

    [LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...

  3. [LOJ#516]「LibreOJ β Round #2」DP 一般看规律

    [LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...

  4. [LOJ#515]「LibreOJ β Round #2」贪心只能过样例

    [LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...

  5. [LOJ#525]「LibreOJ β Round #4」多项式

    [LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...

  6. [LOJ#526]「LibreOJ β Round #4」子集

    [LOJ#526]「LibreOJ β Round #4」子集 试题描述 qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两 ...

  7. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...

  8. loj #547. 「LibreOJ β Round #7」匹配字符串

    #547. 「LibreOJ β Round #7」匹配字符串   题目描述 对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的任意一个长度为 ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

随机推荐

  1. db2字段修改

    db2表字段修改 1:删除字段非空属性alter table XXX alter column XXX drop not null 2:添加字段非空属性alter table XXX alter co ...

  2. GitHub上整理的一些资料

    技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...

  3. Git分支创建与合并

    分支管理是Git支持多人协作和版本控制的关键,参照廖雪峰对Git的介绍,对真实开发环境中Git的使用结合实践进行梳理. 摘自:廖雪峰的官方网站 在实际开发中,我们应该按照几个基本原则进行分支管理: 首 ...

  4. Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)

    本文由  网易云发布. 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意.Flink是原生的流处理系统,提供high level的API.Flink也提 ...

  5. There is No Alternative~最小生成树变形

    Description ICPC (Isles of Coral Park City) consist of several beautiful islands. The citizens reque ...

  6. kaggle入门项目:Titanic存亡预测(三)数据可视化与统计分析

    ---恢复内容开始--- 原kaggle比赛地址:https://www.kaggle.com/c/titanic 原kernel地址:A Data Science Framework: To Ach ...

  7. 批处理(Batch)---批处理脚本。

    批处理(Batch),也称为批处理脚本.顾名思义,批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中.批处理文件的扩展名为bat .目前比较常见的批 ...

  8. BOM和DOM的区别

    一.BOM和DOM之间的关系图 window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象由于window是顶层对象,因此调用它的子对象时可以不显示的指明 ...

  9. Java并发之ReentrantReadWriteLock

    上篇文章简单的介绍了ReentrantLock可重入锁.事实上我们可以理解可重入锁是一种排他锁,排他锁在同一个时刻只能够由一个线程进行访问.这就与我们实际使用过程中有点不想符合了,比如说当我们进行读写 ...

  10. 命令行备忘录 cli-memo

    前言 有时候想用一个简洁点儿的备忘录,发现没有简洁好用的,于是就想着开发一个,秉着简洁 的思想,所以连界面都没有,只能通过命令行来操作(尽可能的将命令简化).设计的时候 借鉴了git分支的思想,每个备 ...