将其连有向边$(i,c_{i})$,由于每一个点出入度都为1,那么必然构成若干个环

对于每一个环,从一点出发,将搜到的点依次记录下来(直至返回自己),记作$v_{1},v_{2},...,v_{k}$,那么就有$c_{v_{i}}=v_{i+1}$(特别的,$c_{v_{k}}=v_{1}$)

显然可以将其看作一个$\{1,2,...,k\}$到$\{v_{1},v_{2},...,v_{k}\}$的映射,即可以简化为$\{2,3,...,n,1\}$如何解决,有一个$n+1$次的做法,具体操作过程如下:$(2,n)$,$(3,n)$,...,$(n-1,n)$,$(1,n)$,$(1,2)$,$(2,n)$

(特别的,当$n=2$,再找一个无关的数,参考样例中做法即可,也是3次)

如果每一个环都需要加1,那么最终次数就是$n+环数 $,显然次数过多

对于两个大小分别为$x$和$y$的环,类似上面将其描述为$\{2,3,...,x,1,x+2,...,x+y,x+1\}$,我们可以用$x+y$次将其解决,具体操作过程如下:$(x,x+y)$,$(1,x+y)$,$(2,x+y)$,...,$(x-1,x+y)$,$(x+1,x)$,$(x+2,x)$...,$(x+y-1,x)$,$(x,x+y)$

由此,将两个环配对,最终至多剩下一个环,再用前面的方式即可,至多$n+1$次

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mp make_pair
5 vector<int>v[N];
6 vector<pair<int,int> >ans;
7 int n,m,a[N],vis[N];
8 void dfs(int k){
9 if (vis[k])return;
10 v[m].push_back(k);
11 vis[k]=1;
12 dfs(a[k]);
13 }
14 int main(){
15 scanf("%d",&n);
16 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
17 for(int i=1;i<=n;i++)
18 if (!vis[i]){
19 m++;
20 dfs(i);
21 if (v[m].size()==1)v[m--].clear();
22 }
23 for(int i=1;i<m;i+=2){
24 int x=v[i].size(),y=v[i+1].size();
25 ans.push_back(mp(v[i][x-1],v[i+1][y-1]));
26 for(int j=0;j+1<x;j++)ans.push_back(mp(v[i][j],v[i+1][y-1]));
27 for(int j=0;j+1<y;j++)ans.push_back(mp(v[i+1][j],v[i][x-1]));
28 ans.push_back(make_pair(v[i].back(),v[i+1].back()));
29 }
30 if (m&1){
31 if (v[m].size()==2){
32 int x=1;
33 if (v[m][0]==1){
34 if (v[m][1]>2)x=2;
35 else x=3;
36 }
37 ans.push_back(mp(v[m][0],x));
38 ans.push_back(mp(x,v[m][1]));
39 ans.push_back(mp(x,v[m][0]));
40 }
41 else{
42 int x=v[m].size();
43 for(int i=1;i+1<x;i++)ans.push_back(mp(v[m][i],v[m][x-1]));
44 ans.push_back(mp(v[m][0],v[m][x-1]));
45 ans.push_back(mp(v[m][0],v[m][1]));
46 ans.push_back(mp(v[m][1],v[m][x-1]));
47 }
48 }
49 printf("%d\n",ans.size());
50 for(int i=0;i<ans.size();i++)printf("%d %d\n",ans[i].first,ans[i].second);
51 for(int i=0;i<ans.size();i++){
52 int x=ans[i].first,y=ans[i].second;
53 swap(a[x],a[y]);
54 a[x]*=-1,a[y]*=-1;
55 }
56 for(int i=1;i<=n;i++)assert(a[i]==i);
57 }

[cf1491G]Switch and Flip的更多相关文章

  1. Codeforces 1491G - Switch and Flip(构造题)

    Codeforces 题目传送门 & 洛谷题目传送门 obviously,难度高一点的构造题对我来说都是不可做题 首先考虑将排列拆成一个个置换环,也就是 \(\forall i\) 连边 \( ...

  2. HTML5 canvas处理图片的各种效果,包括放大缩小涂鸦等

    http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201502151385.html jQuery 缩放 旋转 裁剪图片 Image Cropper ...

  3. 基于layui+cropper.js实现上传图片的裁剪功能

    最近因项目需求,需要在上传图片的时候先对图片裁剪,然后在上传,所以就有了本文的出现. 开始正文之前,要提一下这个图片的裁剪:图片的裁剪,有前端裁剪,也可以后端裁剪 前端的裁剪我知道的可以分为这么两种: ...

  4. jquery mobile页面切换效果(Flip toggle switch)(注:jQuery移动使用的数据属性的列表。 )

    1.页面切换(data-transition)

  5. OpenJudge/Poj 1753 Flip Game

    1.链接地址: http://bailian.openjudge.cn/practice/1753/ http://poj.org/problem?id=1753 2.题目: 总时间限制: 1000m ...

  6. Glitch-free clock switch

    With multi-frequency clocks being used in today’s devices, it's necessary to switch the source of a ...

  7. Partition:分区切换(Switch)

    在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...

  8. java中if和switch哪个效率快

    首先要看一个问题,if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断:而 switch 只能对基本类型进行数值比较.两者的可比性就仅限在两个基本类型比较的范围内.说到基本类型 ...

  9. [开源]QuickSwitchSVNClient,快速完成SVN Switch的工具

    在实际的开发中,我们一般使用SVN工具进行源代码的管理.在实际的产品开发中,根据项目的一些定制要求,往往需要对某一些代码的修改,但是又不想影响主要的开发,这个时候需要对当前的主分支做一些分支处理(br ...

随机推荐

  1. NOIP模拟74

    前言 我就想说一句,T3 给了一个什么牛马大样例!!!!!!!!,气\(^{TM}\)死我!!!!!!! 我的 \(\mathcal{O}(n)\) 算法始终过不掉大样例我 TM ,要不然我就直接上矩 ...

  2. Java学习路线【转】

    Java学习路线[转] 第一阶段:JavaSE(Java基础部分) Java开发前奏 计算机基本原理,Java语言发展简史以及开发环境的搭建,体验Java程序的开发,环境变量的设置,程序的执行过程,相 ...

  3. windows下编译caffe出现错误 C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe?

    解决方案来自http://blog.csdn.net/u012556077/article/details/50353818

  4. Java(45)JDK新特性之String流

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201671.html 博客主页:https://www.cnblogs.com/testero ...

  5. Java(24)常用API三

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228417.html 博客主页:https://www.cnblogs.com/testero ...

  6. 什么是Sprint计划?

    Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...

  7. HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

    TL;DR 迫于 PatchAsJsonAsync 方法缺失,我给 dotnet/runtime 项目贡献了相关的 API,可惜要到 .NET7 才能用上. https://github.com/do ...

  8. 【二食堂】Beta - Scrum Meeting 12

    Scrum Meeting 12 例会时间:5.27 20:00~20:10 进度情况 组员 当前进度 今日任务 李健 1. 知识图谱导出功能完成 issue 1. 继续完成文本保存的工作 issue ...

  9. OO_JAVA_表达式求导

    OO_JAVA_表达式求导_第一弹 ---------------------------------------------------表达式提取部分 词法分析 ​ 首先,每一个表达式内部都存在不可 ...

  10. 轻松掌握stm32直流电机驱动与测速

    说实话就现在的市场应用中stm32已经占到了绝对住到的地位,51已经成为过去式,32的功能更加强大,虽然相应的难度有所增加,但是依然阻止不了大家学习32的脚步,不说大话了这些大家都懂要不然也不会学习s ...