题目大意:

  传送门

  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. c# 获取TFS结构 文件

    #region 获取最新版本 /// <summary> /// 获取最新版本 /// </summary> /// <param name="server_u ...

  2. 浅谈 RxAndroid + Retrofit + Databinding

    http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0131/3930.html 最近 RxAndroid .MVP.MVVM 一直是 And ...

  3. meta 标签知识汇总

    概要 标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务. -- W3School ...

  4. python笔记:#002#第一个python程序

    第一个 Python 程序 目标 第一个 HelloPython 程序 Python 2.x 与 3​​.x 版本简介 执行 Python 程序的三种方式 解释器 -- python / python ...

  5. Unity5 assetbundle笔记

    Assetbundle api试验----打包选项试验--------结论:BuildAssetBundleOptions说明:------------None: 把所有以来资源到到一个包里----- ...

  6. sql语句联表更新(从一个数据库中的一张表更新到另一个数据库的另一张表)

    一.sql server数据库写法: update a set a.ksgmm=b.ksgmm,a.ksgm=b.ksgm,a.scztm=b.scztm,a.sczt=b.sczt from lan ...

  7. QT中对内存的管理

    在QT中,一切继承自QT自有类的类,如果存在parent指针,那么当parent指针delete时,该类中的指针(它们都属于parent指针对应的child指针)也会被delete.综上,如果我们的窗 ...

  8. 重温《STL源码剖析》笔记 第二章

    源码之前,了无秘密. --侯杰 第二章:空间配置器 allocator SGI特殊的空间配置器,std::alloc SGI是以malloc()和free()完成内存的配置与释放. SGI设计了双层级 ...

  9. thinkphp---ajax实现删除

    $(document).ready(function(){ $("a[data]").click(function(){ var data = $(this).attr('data ...

  10. HBuilder 打包流程

    1.运行HBuilder---百度搜索HBuilder,官网下载安装包,解压,运行HBuilder.exe.注册账号,并登陆 2.新建app---在左边右键,选择新建APP,或者,点击中间的新建app ...