Permutation Swaps

传送门

题目理解

第一个操作:把第i个数移到位置p[i](1<=i<=n)

发现:这个操作其实就是循环移位,有Teleporter的经验在前,此操作可用倍增\(\log_{2}^{n}\)实现,同时可 以推出此操作可以叠加,所以用一个sum记录操作次数,查询时一次解决

第二个操作:交换两个位置,此操作较复杂,详见后文

第三个操作:查询x位置数的值

结论:在不考虑第二个操作的情况下,对sum进行二进制拆分,并用预处理好的\(f_k(u)\)[1]更新x

做法

因为第二个操作需要改变原序列位置,所以改变后直接查询\(f_k\)函数会错,这时,就需要运用逆思想:正着不行,倒着来。

在这里,我们需要用到一个数学结论

\[当f是集合A到集合B的一个满映射时\\
\exists B到A的映射g使得g(f(i))=i\\
我们称g是f的反函数
\]

​ 我们对\(p\)处理出它的反函数\(g\),并对其处理倍增ST表,我们可以发现查询\(f_k\)时查询的是位置,所以做第二个操作时,交换的不是 x 和 y ,而是\(ST_k(x)\)和\(ST_k(y)\)。并且因为\(f_k\)查询的是位置,于是我们直接交换这两个值不影响结果。

​ 预处理:对于\(f\)我们可以发现\(f_k(u)=f_{k-x}(f_x(u))\),所以对于\(\forall\)u预处理\(f_{2^b}(u)\)(b<=\(\log_{2}^{n}\)),计算\(f_k(u)\)时,对k进行二进制拆分并更新。例如:对于\(k=13\),可以写成\(13=8+4+1\),于是有\(f_{13}(u)=f_8(f_4(f_1(u)))\)。

​ 最后看实现

code:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, K = 17;
int t, n, a[N], p[N];
int g[N], ST[K + 5][N];
int q, op, sum;
inline void init() {
sum = 0;
for (int i = 1;i <= n;i++) g[p[i]] = i;
for (int i = 1;i <= n;i++) ST[0][i] = g[i];
for (int i = 1;i < K;i++)
for (int j = 1;j <= n;j++)
ST[i][j] = ST[i - 1][ST[i - 1][j]];
}
inline int getback(int x, int k) {
for (int i = K - 1;i >= 0;i--)
if ((k >> i) & 1) x = ST[i][x];
return x;
}
inline void solve() {
if (op == 1) sum++;
if (op == 2) {
int x, y;
scanf("%d%d", &x, &y);
int gx = getback(x, sum), gy = getback(y, sum);
swap(a[gx], a[gy]);
}
if (op == 3) {
int x;
scanf("%d", &x);
int gx = getback(x, sum);
printf("%d\n", a[gx]);
}
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1;i <= n;i++) scanf("%d", &a[i]);
for (int i = 1;i <= n;i++) scanf("%d", &p[i]);
init();
scanf("%d", &q);
while (q--) {
scanf("%d", &op);
solve();
}
}
return 0;
}

  1. 位置为u的跳2k

Permutation Swaps的更多相关文章

  1. Swaps in Permutation

    Swaps in Permutation You are given a permutation of the numbers 1, 2, ..., n and m pairs of position ...

  2. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

  3. codeforces 691D D. Swaps in Permutation(dfs)

    题目链接: D. Swaps in Permutation time limit per test 5 seconds memory limit per test 256 megabytes inpu ...

  4. CodeForces 691D:Swaps in Permutation(并查集)

    http://codeforces.com/contest/691/problem/D D. Swaps in Permutation   You are given a permutation of ...

  5. Codeforces 691D Swaps in Permutation

    Time Limit:5000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Prac ...

  6. Educational Codeforces Round 14 D. Swaps in Permutation

    题目链接 分析:一些边把各个节点连接成了一颗颗树.因为每棵树上的边可以走任意次,所以不难想出要字典序最大,就是每棵树中数字大的放在树中节点编号比较小的位置. 我用了极为暴力的方法,先dfs每棵树,再用 ...

  7. codeforces 691D Swaps in Permutation DFS

    这个题刚开始我以为是每个交换只能用一次,然后一共m次操作 结果这个题的意思是操作数目不限,每个交换也可以无限次 所以可以交换的两个位置连边,只要两个位置连通,就可以呼唤 然后连通块内排序就好了 #in ...

  8. Educational Codeforces Round 14 D. Swaps in Permutation (并查集orDFS)

    题目链接:http://codeforces.com/problemset/problem/691/D 给你n个数,各不相同,范围是1到n.然后是m行数a和b,表示下标为a的数和下标为b的数可以交换无 ...

  9. 【搜索】【并查集】Codeforces 691D Swaps in Permutation

    题目链接: http://codeforces.com/problemset/problem/691/D 题目大意: 给一个1到N的排列,M个操作(1<=N,M<=106),每个操作可以交 ...

  10. Educational Codeforces Round 14 D. Swaps in Permutation(并查集)

    题目链接:http://codeforces.com/contest/691/problem/D 题意: 题目给出一段序列,和m条关系,你可以无限次互相交换这m条关系 ,问这条序列字典序最大可以为多少 ...

随机推荐

  1. Linux中的用户管理-创建删除修改

    用户管理 一.用户分类 用户分为三类: 1.管理员 root root UID:0 #拥有最高权限 默认系统中就一个 UID即user ID 类似于身份号码,唯一的,不可重复 2.虚拟用户 作用:在运 ...

  2. JS 正则表示式 字符串匹配 忽略大小写

    在项目中遇到了需要使用字符串进行正则匹配,同时还要忽略大小写可以按照以下方法:1 先使用new RegExp(newVal, 'i')生成需要匹配的规则,其中 'i' 表示忽略大小写2 再对相应的字符 ...

  3. JAVA 注解示例 详解

    注解(Annotation) 为我们在代码中天界信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据). 注解的语法比较简单,除了@符号的使用以外, ...

  4. 基于antlr的表达式解析器——函数类型验证

    package daicy.formula.evaluator; import java.util.HashMap; import java.util.Map; import org.antlr.ru ...

  5. LeetCode题集-5 - 最长回文子串(一)

    题目:给你一个字符串 s,找到 s 中最长的回文子串. 这一题作为中等难度,常规解法对于大多数人应该都没有难度.但是其中也有超难的解决办法,下面我们就一起由易到难,循序渐进地来解这道题. 01.暴力破 ...

  6. WinForm(C/S)项目中使用矢量字体(FontAwsome、Elegant)图标

    1.介绍 字体图标在Web应用中最为常见,字体图标是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真.字体图标常见的有Font Awesome和Elega ...

  7. DataGridView频繁更新PLC报警信息数据源

    1.问题描述 当DataGridView频繁更新数据源时,可能会导致界面闪烁.性能下降等问题.这是因为每次更新数据源时,DataGridView都需要重新绘制和绑定数据,这是一个相对耗时的过程. 2. ...

  8. Windows安装redis并将redis设置成服务开机自启

    Redis 作为一种缓存工具,主要用于解决高并发的问题,在分布式系统中有着极其广泛的应用,Redis 本身是应用于 Linux/Unix 平台的(部署在服务器上边),官方并没有提供 Windows 平 ...

  9. Dapr-2: 世界是分布式的

    第 2 章 世界是分布的 只需要问任何达人:现代的.分布式的系统已经到来,单体应用已经过时. 但是,不仅是达人,渐进的 IT 领袖,企业架构师,以及精明的开发者,在探寻和评估现代分布式应用的时候,也在 ...

  10. 【C#】【平时作业】习题-10-委托

    什么是委托? C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针. 委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变. 委托(Delegat ...