Solution -「ARC 110F」Esoswap
\(\mathcal{Description}\)
Link.
给定 \(0\sim n-1\) 的排列 \(p_{0..n-1}\),每次操作给出 \(i\),交换 \(p_i\) 和 \(p_{(i+p_i)\bmod n}\)。构造一种使排列升序的操作序列。
\(n\le100\)。
\(\mathcal{Solution}\)
反正兔子就一个样例观察法,一个暴力伪解拍上去就 AC 了。(
先讲讲我的伪解,观察样例解释:
First, announce \(i=6\). We swap \(P_6(=5)\) and \(P_{(6+5)\bmod8}=P_3(=6)\), turning \(P\) into \(7,1,2,5,4,0,6,3\).
Then, announce \(i=0\). We swap \(P_0(=7)\) and \(P_{(0+7)\bmod8}=P_7(=3)\), turning \(P\) into \(3,1,2,5,4,0,6,7\).
Then, announce \(i=3\). We swap \(P_3(=5)\) and \(P_{(3+5)\bmod8}=P_0(=3)\), turning \(P\) into \(5,1,2,3,4,0,6,7\).
Finally, announce \(i=0\). We swap \(P_0(=5)\) and \(P_{(0+5)\bmod8}=P_5(=0)\), turning \(P\) into \(0,1,2,3,4,5,6,7\).
发现三次 \(p_i=5\),一次 \(p_i=7\)。考虑到样例的迷惑性,我们尝试让对 \(p_i=5\) 的操作挨在一起。交换第一步和第二步,发现操作序列仍合法。
接下来,我们强行解释该操作序列的内在逻辑:
- 希望 \(p_7=7\),反复操作 \(p_i=7\) 直到 \(p_7=7\);
- 希望 \(p_7=7\land p_6=6\),反复操作 \(p_i=6\)(样例中不需要操作),直到不满足 \(p_7=7\) 回到第一步,或满足 \(p_6=6\);
- 希望 \(p_5=5\land p_6=6\land p_7=7\),操作同上。
- ……
综上,交换策略为
选择不满足 \(p_i=i\) 的最大的 \(p_i\) 进行交换直到序列升序。
然后就 AC 了,复杂度不知道。(
正解是先操作使得 \(p=\{n-1,n-2,\cdots,0\}\) 然后逆序。操作方法考察从后往前的每个 \(i\),不断操作 \(i\) 直至 \(p_i=n-i-1\),可证至多操作 \(\mathcal O(n)\) 次,总复杂度 \(\mathcal O(n^2)\)。
\(\mathcal{Code}\)
伪解:
/* Clearink */
#include <cstdio>
#include <vector>
#define rep( i, l, r ) for ( int i = l, rpbound##i = r; i <= rpbound##i; ++i )
#define per( i, r, l ) for ( int i = r, rpbound##i = l; i >= rpbound##i; --i )
const int MAXN = 100;
int n, p[MAXN + 5];
std::vector<int> ans;
inline void iswp ( int& a, int& b ) { a ^= b ^= a ^= b; }
int main () {
scanf ( "%d", &n );
rep ( i, 0, n - 1 ) scanf ( "%d", &p[i] );
while ( true ) {
int irr = -1;
rep ( i, 0, n - 1 ) if ( i ^ p[i] && ( !~irr || p[i] > p[irr] ) ) irr = i;
if ( !~irr ) break;
ans.push_back ( irr );
iswp ( p[irr], p[( irr + p[irr] ) % n] );
}
printf ( "%d\n", ( int ) ans.size () );
for ( int i: ans ) printf ( "%d\n", i );
return 0;
}
正解:
/* Clearink */
#include <cstdio>
#include <vector>
#define rep( i, l, r ) for ( int i = l, rpbound##i = r; i <= rpbound##i; ++i )
#define per( i, r, l ) for ( int i = r, rpbound##i = l; i >= rpbound##i; --i )
const int MAXN = 100;
int n, p[MAXN + 5];
std::vector<int> ans;
inline void iswp ( int& a, int& b ) { a ^= b ^= a ^= b; }
inline void oper ( const int i ) {
ans.push_back ( i ), iswp ( p[i], p[( i + p[i] ) % n] );
}
int main () {
scanf ( "%d", &n );
rep ( i, 0, n - 1 ) scanf ( "%d", &p[i] );
per ( i, n - 1, 1 ) for ( ; p[i] != n - i - 1; oper ( i ) );
per ( i, n - 2, 0 ) {
rep ( j, i + 1, n - 2 ) oper ( j );
oper ( i ), oper ( i );
}
printf ( "%d\n", ( int ) ans.size () );
for ( int i: ans ) printf ( "%d\n", i );
return 0;
}
Solution -「ARC 110F」Esoswap的更多相关文章
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「ARC 101D」「AT4353」Robots and Exits
\(\mathcal{Description}\) Link. 有 \(n\) 个小球,坐标为 \(x_{1..n}\):还有 \(m\) 个洞,坐标为 \(y_{1..m}\),保证上述坐标 ...
- Solution -「ARC 110D」Binomial Coefficient is Fun
\(\mathcal{Description}\) Link. 给定非负整数序列 \(\{a_n\}\),设 \(\{b_n\}\) 是一个非负整数序列且 \(\sum_{i=1}^nb_i\ ...
- Solution -「ARC 124E」Pass to Next
\(\mathcal{Description}\) Link. 有 \(n\) 个人站成一个环,初始时第 \(i\) 个人手里有 \(a_i\) 个球.第 \(i\) 个人可以将自己手中任意数 ...
- Solution -「ARC 126E」Infinite Operations
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\),定义一次操作为: 选择 \(a_i<a_j\),以及一个 \(x\in\mathbb R ...
- Solution -「ARC 126F」Affine Sort
\(\mathcal{Description}\) Link. 给定 \(\{x_n\}\),令 \[f(k)=\left|\{(a,b,c)\mid a,b\in[0,c),c\in[1,k ...
- Solution -「ARC 125F」Tree Degree Subset Sum
\(\mathcal{Description}\) Link. 给定含有 \(n\) 个结点的树,求非负整数对 \((x,y)\) 的数量,满足存在 \(\exist S\subseteq V ...
- Solution -「ARC 125E」Snack
\(\mathcal{Description}\) Link. 把 \(n\) 种零食分给 \(m\) 个人,第 \(i\) 种零食有 \(a_i\) 个:第 \(i\) 个人得到同种零食数量 ...
- Solution -「ARC 058C」「AT 1975」Iroha and Haiku
\(\mathcal{Description}\) Link. 称一个正整数序列为"俳(pái)句",当且仅当序列中存在连续一段和为 \(x\),紧接着连续一段和为 \(y ...
随机推荐
- java邮件打包在linux备份数据库练习
注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6812982512256549387/ 承接上一篇文档<Java实现163邮箱发送邮件到QQ邮箱> 主方 ...
- HDU 2673-shǎ崽 OrOrOrOrz(C语言描述)
问题描述 问题是: 为您提供了一系列不同的整数, 请选择 "数字" 如下: 首先选择最大的, 然后是最小的, 然后是第二个最大的, 第二个最小的. 直到所有的数字被选中.例如, 给 ...
- flutter之搭建环境
一. 环境搭建1.安装Flutter SDK 使用Flutter开发,首先我们需要安装一个Flutter的SDK. 下载Flutter的SDK 来到Flutter的官网网站,选择最新稳定的Flutte ...
- 面渣逆袭:Java并发六十问,快来看看你会多少道!
大家好,我是老三,面渣逆袭 继续,这节我们来盘一盘另一个面试必问知识点--Java并发. 这篇文章有点长,四万字,图文详解六十道Java并发面试题.人已经肝麻了,大家可以点赞.收藏慢慢看!扶我起来,我 ...
- CTF-sql-宽字节注入
本文章主要涉及sql宽字节注入注入的原理讲解,如有错误,望指出.(附有目录,如需查看请点右下角) 一.首先介绍一下本篇文章所用到的知识点: 常用到的url编码: 空格:%20 单引号:%27 在sql ...
- Android官方文档翻译 七 2.Adding the Action Bar
Adding the Action Bar 增加一个Action Bar(工具栏) The action bar is one of the most important design element ...
- Linuxqq shell脚本安装后的卸载
官方下载和帮助页面: 传送门 linuxqq_2.0.0-b1 的时候,并没有发布 MIPS64 的 DEB 包,只能用 .sh 安装,需要手动删除卸载.愚人节发布的 beta2 新增了 MIPS64 ...
- [硬件]USB TYPE C引脚定义
- python文档1-unittest单元测试之mock
什么是mock unittest.mock是一个用于在Python中进行单元测试的库,Mock翻译过来就是模拟的意思,顾名思义这个库的主要功能是模拟一些东西.它的主要功能是使用mock对象替代掉指定的 ...
- gin框架使用Air实时加载
Air实时加载 本章我们要介绍一个神器--Air能够实时监听项目的代码文件,在代码发生变更之后自动重新编译并执行,大大提高gin框架项目的开发效率. 1.1.1. 为什么需要实时加载? 之前使用Pyt ...