\(\mathcal{Description}\)

  Link.(几乎一致)

  给定 \(n\) 个点 \(m\) 条边的仙人掌和起点 \(s\),边长度均为 \(1\)。令 \(d(u)\) 表示 \(u\) 到 \(s\) 的最短距离。对于任意一个结点的排列 \(\{p_1,p_2,\cdots,p_n\}\),记 \(t_i\) 满足 \(p_{t_i}=i\),称排列合法,当且仅当:

\[(\forall(u,v)\in E)\left((d(u)<d(v)\rightarrow t_u<t_v)\land(d(u)>d(v)\rightarrow t_u>t_v)\right)
\]

  求合法排列数,对 \(998244353\) 取模。

  \(n\le10^4\),\(m\le2\times10^4\),保证不存在 \((u,v)\in E\),使得 \(d(u)=d(v)\)

\(\mathcal{Solution}\)

  考虑一个偶环(题目保证无奇环),起点终点在左右两端,上下各有 \(l\) 个结点相连。可见上下的点间是互不影响的,我们只需要分别保证上方和下方结点的相对位置

  再考虑一棵树,每个结点必须先于其子树内的点出现,所有方案为 \(n!\),每个结点 \(u\) 就会使其 \(\times\frac{1}{siz_u}\)。

  对于仙人掌,处理出一棵 BFS 树,并得到环的信息。对于非环上的点,直接按树上的点来贡献系数。否则,对于一个环,如图:

  DP 求解,当前子树顺序已确定,令 \(f(i,j)\) 表示用左边前 \(i\) 个和右边前 \(j\) 个时对答案贡献的系数。转移比较显:

\[f(i,j)=\frac{1}{siz_i+siz_j}(f(i-1,j)+f(i,j-1))
\]

  其中 \(siz_i\) 表示 \(i\) 在 BFS 树上的子树大小,需要特殊处理 \(i=0\) 或 \(j=0\) 的情况。

\(\mathcal{Code}\)

#include <queue>
#include <cstdio>
#include <vector> typedef std::pair<int, int> pii; const int MAXN = 1e4, MAXM = 2e4, MOD = 998244353;
int n, m, s, ecnt = 1, inv[MAXN + 5], head[MAXN + 5], dist[MAXN + 5];
int fa[MAXN + 5], siz[MAXN + 5], sL[MAXN + 5], sR[MAXN + 5], f[MAXN + 5][MAXN + 5];
bool cut[MAXM + 5], vis[MAXN + 5];
std::vector<pii> cir; struct Edge { int to, nxt; } graph[MAXM * 2 + 5]; inline void link ( const int s, const int t ) {
graph[++ ecnt] = { t, head[s] };
head[s] = ecnt;
} inline void initBFTree () {
std::queue<int> que;
que.push ( s ), dist[s] = 1;
while ( !que.empty () ) {
int u = que.front (); que.pop ();
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( !dist[v = graph[i].to] ) {
fa[v] = u, dist[v] = dist[u] + 1;
que.push ( v );
} else if ( dist[v] > dist[u] ) {
cut[i >> 1] = true;
cir.push_back ( pii ( u, v ) );
}
}
}
} inline void initSize ( const int u ) {
siz[u] = 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( !cut[i >> 1] && ( v = graph[i].to ) ^ fa[u] ) {
initSize ( v ), siz[u] += siz[v];
}
}
} int main () {
freopen ( "abgfriend.in", "r", stdin );
freopen ( "abgfriend.out", "w", stdout );
scanf ( "%d %d %d", &n, &m, &s );
int ans = inv[1] = 1;
for ( int i = 2; i <= n; ++ i ) {
ans = 1ll * i * ans % MOD;
inv[i] = 1ll * ( MOD - MOD / i ) * inv[MOD % i] % MOD;
}
for ( int i = 1, u, v; i <= m; ++ i ) {
scanf ( "%d %d", &u, &v );
link ( u, v ), link ( v, u );
}
initBFTree ();
initSize ( s );
for ( int i = 0; i ^ cir.size (); ++ i ) {
int u = cir[i].first, v = cir[i].second, cnt = 0;
for ( int p = u, q = fa[v]; p ^ q; p = fa[p], q = fa[q] ) {
vis[p] = vis[q] = true, ++ cnt;
sL[cnt] = siz[p], sR[cnt] = siz[q];
}
for ( int i = 0; i <= cnt; ++ i ) {
for ( int j = 0; j <= cnt; ++ j ) {
if ( !i && !j ) f[i][j] = 1;
else if ( !i ) f[i][j] = 1ll * f[i][j - 1] * inv[sR[j]] % MOD;
else if ( !j ) f[i][j] = 1ll * f[i - 1][j] * inv[sL[i] + siz[v]] % MOD;
else f[i][j] = 1ll * ( f[i - 1][j] + f[i][j - 1] ) * inv[sL[i] + sR[j]] % MOD;
}
}
ans = 1ll * ans * f[cnt][cnt] % MOD;
}
for ( int i = 1; i <= n; ++ i ) {
if ( !vis[i] ) {
ans = 1ll * ans * inv[siz[i]] % MOD;
}
}
printf ( "%d\n", ans );
return 0;
}

\(\mathcal{Details}\)

  一开始局部变量 cnt 没赋初值,Windows 贴心地帮助兔子清了零,然后在 Lemon 上测 RE 一大片 qwq……

Solution -「LOCAL」「cov. HDU 6864」找朋友的更多相关文章

  1. Solution -「LOCAL」「cov. HDU 6816」折纸游戏

    \(\mathcal{Description}\)   Link(削弱版).   \(n\) 张纸叠在一起对折 \(k\) 次,然后从上到下为每层的正反两面写上数字,求把纸重新摊平后每张纸上的数字序列 ...

  2. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  3. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  4. 【翻译】西川善司的「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,后篇

    http://www.4gamer.net/games/216/G021678/20140714079/     连载第2回的本回,  Arc System Works开发的格斗游戏「GUILTY G ...

  5. Android内存管理(4)*官方教程 含「高效内存的16条策略」 Managing Your App's Memory

    Managing Your App's Memory In this document How Android Manages Memory Sharing Memory Allocating and ...

  6. SSH连接时出现「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」解决办法

    用ssh來操控github,沒想到連線時,出現「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」,後面還有一大串英文,這時當然要向Google大神求助 ...

  7. 「Windows MFC 」「Edit Control」 控件

    「Windows MFC 」「Edit Control」 控件

  8. 「ZJOI2019」&「十二省联考 2019」题解索引

    「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...

  9. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

随机推荐

  1. Java实现单词统计

    原文链接: https://www.toutiao.com/i6764296608705151496/ 单词统计的是统计一个文件中单词出现的次数,比如下面的数据源 其中,最终出现的次数结果应该是下面的 ...

  2. HDU 1106 (1.3.5) 排序 (C语言描述)

    排序 Problem Description 输入一行数字,如果我们把这行数字中的'5'都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以'0'开头,这些头部的'0'应该被忽略掉,除非 ...

  3. Flutter 2022 产品路线图发布

    为了提升产品的透明性,每年年初 Flutter 团队都会发布今年度的产品路线图,以帮助使用 Flutter 的团队和开发者们根据这些优先事项制定计划. 2022 年 Flutter 团队将重点通过关注 ...

  4. 【Java常用类】System

    System System类代表系统,系统级的很多属性和控制方法都放置在该类的内部. 该类位于java.lang包.由于该类的构造器是private的,所以无法创建该类的对象,其内部的成员变量和成员方 ...

  5. 新设备关联Gitlab

    新设备关联Gitlab 1:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果 ...

  6. rocketmq实现延迟队列精确到秒级实现方案1-代理实现

    简单的来说,就是rocketmq发送消息到broker的时候,判断是否定时消息, 如果是定时消息,将消息发送到代理服务(这个是一个独立的服务,需要自己开发,定时地把消息发送出去), 当然了消息用什么来 ...

  7. 【get√】golang新手理解了一点点context

    测试代码如下: package practice import ( "context" "log" //"fmt" "time&q ...

  8. 带你学习BFS最小步数模型

    最小步数模型 一.简介 最小步数模型和最短路模型的区别? 最短路模型:某一个点到另一个点的最短距离(坐标与坐标之间) 最小步数模型:不再是点(坐标),而是状态到另一个状态的转变 BFS难点所在(最短路 ...

  9. load-on-startup元素:控制Servlet启动优先级

    load-on-startup 是 web.xml 中的一个节点,是 servlet 元素的子元素,用来标记 Servlet 容器启动时是否初始化当前 Servlet,以及当前 Servlet 的初始 ...

  10. find -or 用法

    find /opt/IBM/WebSphere85/ -name *loggeter* - or -name *loggetter* | xargs rm -rf