稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数

一个挺trick的想法是:

由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和

那么如果把不存在于原树中的边的边权设为x,做矩阵树定理得到n-1次的多项式第i次项系数就是选择新选择i个边的方案数!

带着x不好做,x=1~n带入,然后插值即可

O(n^4)

开始碾标算了:

还是可以树形DP,经典的树形DP套路难办的原因是不知道干掉的子树接在哪里

所以我们干脆先不管接在哪里,先都砍断

一个公式:

https://rqy.moe/Solutions/bzoj5475/

证明导数第二步有点生成函数的思想了

对于拆成k个连通块,方案数可以直接算

设f[i][j][k],以i为根子树保留j条边,和i相连的连通块sz为k的方案数。枚举子树保留边数和sz就可以愉快转移了

但是会算重

如果直接乘上n^(k-2)可能会把断的边连回去,不止保留了j个,并且同一个方案可能因为保留的不同的j个计算多次!

不慌不慌

一切都是因为实际上可能连回去保留了不止j个,我们钦定了j个,其他随便选的方案数是f,

枚举具体保留了几个,可以二项式反演

$f[t]=\sum_{k=t}^{n} C(k,t)*ans[k]$

ans表示恰好保留了k个

没了

O(n^3)

进一步优化!

$\Pi a_i$有组合意义,就是对于k个连通块,我们每个连通块恰好选择一个点的方案数!

f[i][j][0/1],表示,,,,,i这个连通块内有没有选择点,总方案数

愉快转移,断边必须y选择。

代码

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=;
const int mod=;
int n,k;
int qm(int x,int y){
int ret=;while(y){
if(y&) ret=(ll)ret*x%mod;x=(ll)x*x%mod;
y>>=;
}return ret;
}
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
int ad(int x,int y){
return x+y>=mod?x+y-mod:x+y;
}
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
int sz[N];
int f[N][N][];
int C[N][N];
ll ans[N],dp[N];
void dfs(int x,int fa){
sz[x]=;
f[x][][]=f[x][][]=;
int g[][N][];
memset(g[],,sizeof g[]);
//memset(g,0,sizeof g);
g[][][]=g[][][]=;
int tmp=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
dfs(y,x);
tmp^=;
//for(reg j=0;j<sz[x]+sz[y];++j) g[tmp][j][0]=g[tmp][j][1]=0;
memset(g[tmp],,sizeof g[tmp]);
for(reg j=;j<sz[x];++j){
for(reg k=;k<sz[y];++k){
g[tmp][j+k][]=ad(g[tmp][j+k][],(ll)g[tmp^][j][]*f[y][k][]%mod);
g[tmp][j+k][]=ad(g[tmp][j+k][],(ll)g[tmp^][j][]*f[y][k][]%mod); g[tmp][j+k+][]=ad(g[tmp][j+k+][],(ll)g[tmp^][j][]*f[y][k][]%mod);
g[tmp][j+k+][]=ad(g[tmp][j+k+][],ad((ll)g[tmp^][j][]*f[y][k][]%mod,(ll)g[tmp^][j][]*f[y][k][]%mod));
}
}
sz[x]+=sz[y];
}
//cout<<" f "<<x<<endl;
for(reg j=;j<sz[x];++j) {
f[x][j][]=g[tmp][j][],f[x][j][]=g[tmp][j][];
//cout<<j<<" n0 "<<" : "<<f[x][j][0]<<" n1 "<<f[x][j][1]<<endl;
}
}
int main(){
rd(n);rd(k);
if(k==){
puts("");return ;
}
int x;
for(reg i=;i<=n;++i){
rd(x);++x;
add(i,x);add(x,i);
}
dfs(,);
for(reg j=;j<n;++j) {
if(j!=n-) dp[j]=(ll)f[][j][]*qm(n,n-j-);
else dp[j]=;
}
ans[n-]=dp[n-];
C[][]=;
for(reg i=;i<=n;++i){
C[i][]=;
for(reg j=;j<=n;++j){
C[i][j]=(C[i-][j-]+C[i-][j])%mod;
}
}
ll op=ans[n-];
for(reg i=n-;i>=n-k-;--i){
// cout<<" ii "<<i<<" : "<<dp[i]<<endl;
for(reg j=i+;j<n;++j){
dp[i]=(dp[i]+mod-(ll)C[j][i]*ans[j]%mod)%mod;
}
ans[i]=dp[i];
op=(op+dp[i])%mod;
}
printf("%lld",op);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/3/4 19:02:40
*/

思路:

矩阵树:新加k条新边,为了控制边数,所以用x表示边权得到方案数,插值也很漂亮

DP:直接DP难写,受prufer序列的推论启发,考虑对于连通块直接统计,然后二项式反演去重

  组合意义的优化,类似于:[NOI2009]管道取珠

省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  3. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  4. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

  5. NOI2019省选模拟赛 第六场

    传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...

  6. 省选模拟赛 arg

    1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...

  7. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

  8. 5.5 省选模拟赛 B Permutation 构造 贪心

    LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...

  9. 省选模拟赛 4.26 T1 dp 线段树优化dp

    LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...

随机推荐

  1. 【IDEA】Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目

    转载请注明出处:http://blog.csdn.net/qq_26525215本文源自[大学之旅_谙忆的博客] 本篇博客讲解IDEA如何配置Tomcat. 大部分是直接上图哦. 点击如图所示的地方, ...

  2. phpstorm 报错及解决

    1. 当项目里有大量 js 文件时,一旦编辑包含 js 的文件,phpstorm 会卡顿,甚至未响应 问题原因: 内存限制较小 解决方法一: 直接将弹出框中的红色部分修改为需要的内存限制,并选择 Sh ...

  3. 由一个“两次请求”引出的Web服务器跨域请求访问问题的解决方案

    http://blog.csdn.net/cnhnnyzhy/article/details/53128179 (4)Access-Control-Max-Age 该字段可选,用来指定本次预检请求的有 ...

  4. Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)

    Nginx.LVS.HAProxy 是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,通常会结合Keepalive做健康检查,实现故障转移的高可用功能. 1)在四层(tcp)实现负载均衡的 ...

  5. Fedora 19安装mysql

    安装数据库模块 Mysql和Mysql-server#yum install mysql mysql-server 开启mysql服务#systemctl start mysqld.service同样 ...

  6. HTTP基础与Android之(安卓与服务器通信)——使用HttpClient和HttpURLConnection

    查看原文:http://blog.csdn.net/sinat_29912455/article/details/51122286 1客户端连接服务器实现内部的原理 GET方式和POST方式的差别 H ...

  7. div+css实现圆形div以及带箭头提示框效果

    .img{ width:90px; height:90px; border-radius:45px; margin:0 40%; border:solid rgb(100,100,100) 1px;& ...

  8. The import * cannot be resolved

    背景 使用eclipse jee做练习的时候,下载了老师的项目源码.考虑到老师用的时myeclipse,目录结构略有不同,所有不想直接导入项目,又考虑到,可能环境不一样,会出现这样那样的问题,所以我的 ...

  9. 自己写的browse.bat与perl写的url_handler.pl的比较

    以前自己也写过Windows下自动打开多个浏览器测试某个URI,提高浏览器兼容性测试效率. 但是写的browse.bat文件还是最基础简陋的 @echo off if '%1'=='-c' ( sta ...

  10. ESXi安装时遇到不识别的硬件的处理

    1. 部门新购置了一台inspur 四路 NF8480M4的服务器. 上架之后发现ESXi的标准安装盘无法安装. 找不到磁盘安装介质. 2. 处理办法, 找浪潮专家服务,报上序列号,要上相关的一些软件 ...