「UER#2」信息的交换

吉利题..

不难发现,置换中的每一个循环是独立的,每一个循环分别对应一个独立的联通块。

根据题目的性质,每一个联通块做的事情等价于其按照编号从小到大遍历的的dfs生成树做的事情,那么只需要考虑一棵dfs生成树做的事情即可。

对于一棵dfs生成树,将每个点的儿子按照编号从小到大排序,考虑节点 \(u\) 以及它的儿子 \(v_1,v_2..v_k\) ,其中 \(v_k\) 的权值最终会到 \(u\) 的位置上,\(\forall i<k,v_i\) 的值会先到 \(v_{i+1}\) 的位置上去,到访问到 \(v_i+1\) 的时候在继续做同样的事情,最终会到达 \(v_{i+1}\) 这棵子树最左边的叶子上。定义逆dfs序为先遍历编号大的儿子的dfs序,这个过程做完相当于节点 \(v\) 到了逆dfs序的前一位对应的节点上,根节点到逆dfs序上最后一位对应的节点。相当于按照逆dfs序做了一个置换!

那么只需要将每个循环对应的逆dfs序求出来,再计算有多少棵树的逆dfs序符合。对于一棵符合的树,其连上一些返祖边可以得到符合的图,大力DP一下即可,复杂度 \(\mathcal O(n^3)\) 。

code

/*program by mangoyang*/
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 505, mod = 998244353;
int vis[N], pw[N], a[N], f[N][N], h[N][N], c[N][N], n;
inline void up(int &x, int y){ x = x + y >= mod ? x + y - mod : x + y; }
inline int gao(vector<int> &A){
if(!(int) A.size()) return 1;
int m = A.size();
for(int i = 0; i < m; i++)
for(int j = i + 1; j < m; j++)
c[i][j] = c[i][j-1] + (A[j] > A[i]);
for(int i = 0; i < m; i++)
for(int j = 0; j < m; j++) f[i][j] = 0;
for(int i = 0; i < m; i++) f[i][i] = h[i][i] = 1;
for(int i = m - 1; ~i; i--)
for(int j = i + 1; j < m; j++){
f[i][j] = h[i][j] = 1ll * f[i+1][j] * pw[c[i][j]] % mod;
for(int k = i; k < j; k++) if(A[i] > A[k+1])
up(f[i][j], 1ll * h[i][k] * f[k+1][j] % mod);
}
return f[0][m-1];
}
int main(){
read(n), pw[0] = 1;
for(int i = 1; i <= n; i++) read(a[i]);
for(int i = 1; i <= n; i++) pw[i] = 2ll * pw[i-1] % mod;
int ans = 1;
for(int i = 1; i <= n; i++) if(!vis[i]){
vector<int> A;
vis[i] = 1;
for(int p = a[i]; p != i; p = a[p])
A.push_back(p), vis[p] = 1;
ans = 1ll * ans * gao(A) % mod;
}
cout << ans << endl;
}

「UER#2」信息的交换的更多相关文章

  1. 「UER#2」谣言的传播

    「UER#2」谣言的传播 写了个乱搞,怎么莫名其妙就AC了,这...,之后又想了30min结合题解终于会证了. 首先最大值比较简单,记 \(f_i\) 为第 \(i\) 个点能到达的点数,上界 \(\ ...

  2. Diary / Solution Set -「WC 2022」线上冬眠做噩梦

      大概只有比较有意思又不过分超出能力范围的题叭.   可是兔子的"能力范围" \(=\varnothing\) qwq. 「CF 1267G」Game Relics   任意一个 ...

  3. 图解最长回文子串「Manacher 算法」,基础思路感性上的解析

    问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...

  4. 「Android 开发」入门笔记

    「Android 开发」入门笔记(界面编程篇) ------每日摘要------ DAY-1: 学习笔记: Android应用结构分析 界面编程与视图(View)组件 布局管理器 问题整理: Andr ...

  5. 「POJ 3666」Making the Grade 题解(两种做法)

    0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...

  6. 「C语言」文件的概念与简单数据流的读写函数

    写完「C语言」单链表/双向链表的建立/遍历/插入/删除 后,如何将内存中的链表信息及时的保存到文件中,又能够及时的从文件中读取出来进行处理,便需要用到”文件“的相关知识点进行文件的输入.输出. 其实, ...

  7. 「C语言」Windows+EclipseCDT下的C语言开发环境准备

    之前写过一篇 「C语言」在Windows平台搭建C语言开发环境的多种方式 ,讨论了如何在Windows下用DEV C++.EclipseCDT.VisualStudio.Sublime Test.Cl ...

  8. 日均百万 PV 的站点如何做性能监测?试试「3M口罩」!

    对很多开发者而言,如果网站的日流量达到百万级别,峰值 PV 也突破了 3 万,这样的站点在线下测试的时候总是让人心力交瘁.... 生产环境下的性能监测问题更是尤其让人头疼! 开发同学在想,运维人员也在 ...

  9. 微服务架构之「 API网关 」

    在微服务架构的系列文章中,前面已经通过文章<架构设计之「服务注册 」>介绍过了服务注册的原理和应用,今天这篇文章我们来聊一聊「 API网关 」. 「 API网关 」是任何微服务架构的重要组 ...

随机推荐

  1. 初始化错误——从一个简单的算例看UDF各个宏的调用顺序

    感谢西安交通大学en_phert的问题和尝试 Fluent版本:Fluent 19.0 Visual Studio版本:Visual Studio 2013 在UDF的宏的调用中大家常看见下图: 这个 ...

  2. 从工厂流水线小妹到Google上班程序媛,看完后,我跪服了!

    阅读本文大概需要 10.2 分钟. 文作者:Ling Sun 原文链接:https://www.zhihu.com/question/68154951/answer/546265013 我家境很不好, ...

  3. leetcode 877. 石子游戏

    题目描述: 亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最多来决出胜负.石子的总数是奇数,所以没有平局. 亚历克斯和李轮流进行,亚 ...

  4. phpstudy(小皮面板)和phpstudy2018 配置php的区别

    phpstudy(小皮面板)和phpstudy2018 配置php的区别 一.总结 一句话总结: phpstudy(小皮面板) 和 phpstudy2018 只是引入的php的位置不同,但是核心代码还 ...

  5. promise 和 async await比较

    async搭配await是ES7提出的,它的实现是基于Promise.这里使用它对比Promise的用法,这里只是简单的适合日常业务的使用场景.   async.await是ES7中的提案,通过同步方 ...

  6. jQuery 取值操作

    模板使用: https://startbootstrap.com/themes/sb-admin-2/ 使用的 bootstrap 模块 ,上面的这个网站可以下载 select 取值 <sele ...

  7. (转) centos7 RPM包之rpm命令

    原文:https://blog.csdn.net/capecape/article/details/78529159 RPM包与源码包的区别1.软件包分类 源码包:C源代码包 rpm包:编译之后的二进 ...

  8. Springboot配置连接两个数据库

    背景: 项目中需要从两个不同的数据库查询数据,之前实现方法是:springboot配置连接一个数据源,另一个使用jdbc代码连接. 为了改进,现在使用SpringBoot配置连接两个数据源 实现效果: ...

  9. [ARM-Linux开发]linux dmesg命令参数及用法详解(linux显示开机信息命令)

    功能说明:显示开机信息.语 法:dmesg [-cn][-s <缓冲区大小>]补充说明:kernel会将开机信息存储在ring buffer中.您若是开机时来不及查看信息,可利用dmesg ...

  10. Oracle Spatial分区应用研究之四:不同分区粒度+全局空间索引效率对比

    1.实验目的 在实验之前先回答这样一个问题——对同一份数据使用不同的分区粒度,但均创建全局空间索引,问:它们的全局空间索引一致吗? 怎样算是一致的呢?R-TREE的树结构一致算一致吗?空间索引条目数及 ...