当前位置: 首页 > wzjs >正文

长沙正规官网建站江阴网站优化公司

长沙正规官网建站,江阴网站优化公司,找钢网网站建设,地图网站抓取题意 原题链接 简要题意: 给你一棵 n n n 个点的树,你需要将 1 ∼ n 1 \sim n 1∼n 的排列填到树上的节点中。定义一个点为 局部最小值 满足与它相邻的点上的数都比它大。你需要对 k 1 , 2 , . . . , n k 1,2,...,n k1,2,...,n 都输出恰好有 k k…

题意

原题链接

简要题意:
给你一棵 n n n 个点的树,你需要将 1 ∼ n 1 \sim n 1n 的排列填到树上的节点中。定义一个点为 局部最小值 满足与它相邻的点上的数都比它大。你需要对 k = 1 , 2 , . . . , n k = 1,2,...,n k=1,2,...,n 都输出恰好有 k k k 个局部最小值时排列有多少种填法。

1 ≤ n ≤ 500 1 \leq n \leq 500 1n500

分析:
首先看到 恰好,可以考虑二项式反演。如何求出在 钦定 k k k 个局部最小值的情况下的方案数呢?发现如果钦定了一个点 x x x 是局部最小值,那么它和相邻点的大小关系就定了,不妨用一条 x x x 指向相邻点的有向边表示。

但是这样还是不太好做。发现如果有向边能形成一棵树是比较容易计算方案的。如果对于一个钦定的点能只保留指向儿子的有向边,那么这样就会形成若干有向树,每棵树的方案相互独立乘起来即可。

那么一棵有向树的方案怎么算呢?有一个经典结论:对于一个 n n n 个点的有向森林,填充排列满足任意一个点上的数小于它的儿子的方案数为 n ! × ∏ u 1 s z u n! \times \prod\limits_{u}\frac{1}{sz_u} n!×uszu1

那么钦定点指向父亲的边怎么办?考虑容斥成无向(删去这条边)减去反向边即可。

这样就有了一个 d p dp dp。设 f i , j , k f_{i, j, k} fi,j,k 表示考虑了以 i i i 为根的子树,当前钦定了 j j j 个局部最小值, i i i 所在的有向树大小为 k k k,并且 i i i 没有被钦定的方案数。 g i , j , k g_{i, j, k} gi,j,k 则是表示 i i i 已经被钦定。那么转移就是 二维背包,复杂度 O ( n 4 ) O(n^4) O(n4)。注意如果 i i i 的父亲不指向 i i i,那么需要将 1 k \frac{1}{k} k1 乘到答案中。

注意到对于钦定局部最小值这一维的转移 只涉及到加法卷积,并且最后只需要知道根节点的 d p dp dp 数组,考虑拉插优化:首先将第二三维交换顺序,然后将 f i , k f_{i, k} fi,k 看做一个长度为子树大小的多项式, f i , k , j f_{i, k, j} fi,k,j x j x^j xj 的系数。那么对 j j j 这一维的转移就是两个多项式的卷积。 f r o o t , k f_{root, k} froot,k 肯定是一个 n n n 次多项式,因此枚举 x = 1 ∼ n + 1 x = 1\sim n + 1 x=1n+1 求出 n + 1 n + 1 n+1 个点拉插还原系数即可。

枚举 x x x 后每次 d p dp dp 复杂度 O ( n 2 ) O(n^2) O(n2),求点值的复杂度为 O ( n 3 ) O(n^3) O(n3)。最后拉插还原系数可以用 短除法 做到 O ( n 2 ) O(n^2) O(n2),总复杂度 O ( n 3 ) O(n^3) O(n3)

CODE:

// 首先可以二项式反演把恰好改成钦定
// 然后定一个最小值就能把一个点和它周围点的大小关系定下来
// 可以把大小关系用一条有向边表示
// 发现儿子指向父亲是不好搞的,容斥成没有这条边 - 父亲指向儿子 
// 于是就可以得到一个 O(n^4) 的二维背包
// 把dp数组看作系数,插值优化 
// 对于某一维只有加法卷积的转移, 可以拉差优化掉这一维 
#include<bits/stdc++.h>
#define pb emplace_back
using namespace std;
typedef long long LL;
const int mod = 998244353;
const int N = 510;
int n;
int X[N], Y[N]; // n次多项式, 维护 n + 1 个点 
int f[N][N], g[N][N];  
int tf[N], tg[N];
int fac[N], inv[N], Inv[N];
int c[N][N], tmp[N], H[N], F[N], G[N];
int sz[N];
vector< int > E[N];
inline int sign(int x) {return (x & 1) ? mod - 1 : 1;}
inline int Pow(int x, int y) {int res = 1, k = x;while(y) {if(y & 1) res = 1LL * res * k % mod;y >>= 1;k = 1LL * k * k % mod;}return res;
}
void dfs(int x, int fa, int d) { // d 为底数 sz[x] = 1; f[x][1] = 1; g[x][1] = d;for(auto v : E[x]) {if(v == fa) continue;dfs(v, x, d);for(int i = 1; i <= sz[x]; i ++ ) {for(int j = 1; j <= sz[v]; j ++ ) {tf[i] = (tf[i] + 1LL * f[x][i] * f[v][j] % mod * Inv[j] % mod) % mod;tf[i] = (tf[i] + 1LL * f[x][i] * g[v][j] % mod * Inv[j] % mod) % mod;tf[i + j] = (tf[i + j] + 1LL * f[x][i] * g[v][j] % mod * Inv[j] % mod * (mod - 1) % mod) % mod;tg[i + j] = (tg[i + j] + 1LL * g[x][i] * f[v][j] % mod * Inv[j] % mod) % mod;}}sz[x] += sz[v];for(int i = 1; i <= sz[x]; i ++ ) {f[x][i] = tf[i], g[x][i] = tg[i];tf[i] = 0; tg[i] = 0;}}
}
void lag() { // 把 n + 1 个点的系数插出来 for(int i = 0; i <= n; i ++ ) F[i] = 0;for(int i = 0; i <= n + 1; i ++ ) tmp[i] = 0;tmp[0] = 1;for(int i = 1; i <= n + 1; i ++ ) {for(int j = n + 1; j >= 0; j -- ) {tmp[j + 1] = (tmp[j + 1] + tmp[j]) % mod;tmp[j] = (1LL * tmp[j] * X[i] % mod * (mod - 1) % mod) % mod;}}for(int i = 1; i <= n + 1; i ++ ) {int a = 1;a = 1LL * inv[i - 1] * inv[n + 1 - i] % mod * sign(n + 1 - i) % mod * Y[i] % mod;int lst = tmp[n + 1];for(int j = n; j >= 0; j -- ) {F[j] = (F[j] + 1LL * lst * a % mod) % mod;lst = (tmp[j] + 1LL * lst * X[i] % mod) % mod;}}
}
int main() {for(int i = 0; i < N; i ++ ) {for(int j = 0; j <= i; j ++ ) {if(!j) c[i][j] = 1;else c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;}}scanf("%d", &n);fac[0] = 1; for(int i = 1; i <= n; i ++ ) fac[i] = 1LL * fac[i - 1] * i % mod; inv[n] = Pow(fac[n], mod - 2LL);for(int i = n - 1; i >= 0; i -- ) inv[i] = 1LL * inv[i + 1] * (i + 1) % mod;Inv[0] = 1; for(int i = 1; i <= n; i ++ ) Inv[i] = Pow(1LL * i, mod - 2LL);for(int i = 1; i < n; i ++ ) {int u, v; scanf("%d%d", &u, &v);E[u].pb(v); E[v].pb(u);}for(int x = 1; x <= n + 1; x ++ ) {dfs(1, 0, 1LL * x);for(int i = 1; i <= n; i ++ ) {X[x] = x; Y[x] = (Y[x] + 1LL * (f[1][i] + g[1][i]) * Inv[i] % mod) % mod;}}lag();for(int i = 0; i <= n; i ++ ) F[i] = 1LL * F[i] * fac[n] % mod;for(int i = 0; i <= n; i ++ ) {for(int j = i; j <= n; j ++ ) {G[i] = (G[i] + 1LL * c[j][i] * sign(j - i) % mod * F[j] % mod) % mod;}}for(int i = 1; i <= n; i ++ ) printf("%d\n", G[i]);return 0;
}
http://www.dtcms.com/wzjs/2053.html

相关文章:

  • 留学公司网站怎么做中国新冠疫苗接种率
  • Tp5即做网站又提供api接口上海搜索引擎优化公司排名
  • 创客贴做网站吗优化营商环境心得体会2023
  • 平台搭建工具成品网站seo
  • wordpress dux搜索无法使用杭州谷歌seo公司
  • 国外什么网站是做外贸西安百度竞价托管公司
  • 查询网站备案号app网络推广工具和方法
  • 企业网站的建立与维护论文空间刷赞网站推广
  • 结合公众号小店做网站四种营销模式
  • apache 多个网站百度风云榜小说排行榜历届榜单
  • 纸牌网站建设产品营销推广的方案
  • 做一个谷歌网站多少钱seo方式包括
  • 建设网站必须要服务器吗企业管理培训机构
  • 企业网站建设方案书 备案网页首页设计图片
  • 学校专业群建设专题网站电商关键词查询工具
  • 在线工具查看源代码seo站群优化技术
  • 安阳seo公司seo快速排名是什么
  • 做网站商机搜索引擎营销方式
  • 高端服装产品网站建设北京seo管理
  • 广州网站建设教程自媒体营销模式有哪些
  • 建筑网站带图解qq推广引流怎么做
  • 有口碑的武进网站建设seo网络优化是什么意思
  • 电商设计工作职责企业网站优化推广
  • wordpress娱乐资源网360seo排名点击软件
  • 购物帮做特惠的网站外贸网站制作公司
  • 做网站有高手没有千锋教育地址
  • 深圳官方网站制作网站seo服务
  • iis下建立asp网站网络营销的推广手段
  • 学生自做网站优秀作品网站历史权重查询
  • 静态网站怎么做滚动文字百度小说搜索风云榜