[cf1491G]Switch and Flip
将其连有向边$(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的更多相关文章
- Codeforces 1491G - Switch and Flip(构造题)
Codeforces 题目传送门 & 洛谷题目传送门 obviously,难度高一点的构造题对我来说都是不可做题 首先考虑将排列拆成一个个置换环,也就是 \(\forall i\) 连边 \( ...
- HTML5 canvas处理图片的各种效果,包括放大缩小涂鸦等
http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201502151385.html jQuery 缩放 旋转 裁剪图片 Image Cropper ...
- 基于layui+cropper.js实现上传图片的裁剪功能
最近因项目需求,需要在上传图片的时候先对图片裁剪,然后在上传,所以就有了本文的出现. 开始正文之前,要提一下这个图片的裁剪:图片的裁剪,有前端裁剪,也可以后端裁剪 前端的裁剪我知道的可以分为这么两种: ...
- jquery mobile页面切换效果(Flip toggle switch)(注:jQuery移动使用的数据属性的列表。 )
1.页面切换(data-transition)
- OpenJudge/Poj 1753 Flip Game
1.链接地址: http://bailian.openjudge.cn/practice/1753/ http://poj.org/problem?id=1753 2.题目: 总时间限制: 1000m ...
- Glitch-free clock switch
With multi-frequency clocks being used in today’s devices, it's necessary to switch the source of a ...
- Partition:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...
- java中if和switch哪个效率快
首先要看一个问题,if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断:而 switch 只能对基本类型进行数值比较.两者的可比性就仅限在两个基本类型比较的范围内.说到基本类型 ...
- [开源]QuickSwitchSVNClient,快速完成SVN Switch的工具
在实际的开发中,我们一般使用SVN工具进行源代码的管理.在实际的产品开发中,根据项目的一些定制要求,往往需要对某一些代码的修改,但是又不想影响主要的开发,这个时候需要对当前的主分支做一些分支处理(br ...
随机推荐
- 用OpenCV显示视频时遇到问题
刚刚接触OpenCV,运行了书上的例程,程序编译没有问题,在视频显示快要结束时遇到了下面的问题,代码在后面 #include "stdafx.h"#include <open ...
- SQL SERVER数据库权限分配
1,新建 只能访问某一个表的只读用户. --添加只允许访问指定表的用户: exec sp_addlogin '用户名','密码','默认数据库名' ...
- 用C++实现的数独解题程序 SudokuSolver 2.4 及实例分析
SudokuSolver 2.4 程序实现 本次版本实现了 用C++实现的数独解题程序 SudokuSolver 2.3 及实例分析 里发现的第三个不完全收缩 grp 算法 thirdGreenWor ...
- I-Base62
I - Base62 PS:一个任意进制转换的大数问题 传送门:Base62 短除法原理: 20(10进制) => 202(3进制) 20 = (2 * 3 ^ 2 + 0 * 3 ^ 1 + ...
- UltraSoft - Alpha - 发布声明
DDL_Killer Alpha版本发布声明 1. Alpha 阶段功能描述与版本实现 功能描述 设计原型 Alpha实现 登陆界面 注册界面 首页 日历视图 事项详情页 新建事项 列表视图 课程视图 ...
- proto3语法记录
protobuf 是谷歌的语言无关,平台无关,可扩展的,高效的结构化数据序列化机制,比xml和json的序列化的速度更快,此处记录一下 proto3 的语法,防止以后忘记. 注意:proto3 语法需 ...
- hystrix的配置说明
在我们的日常开发中,有些时候需要和第三方系统进行对接操作,或者调用其他系统的 api 接口,但是我们不能保证这些第三方系统的接口一定是稳定的,当系统中产生大量的流量来访问这些第三方接口,这些第三方系统 ...
- Noip模拟80 2021.10.18
预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...
- 2019.03.27【GDOI2019】模拟 T3
题目大意 给出$n$, $p$, 求有多少长度为$n$的排列可以被分成三个上升子序列, 数量对$p$取模, 数据范围 $3 \leq n \leq 500$. 思路 首先让我们考虑如果有一个排列,如何 ...
- 『学了就忘』Linux基础 — 6、VMware虚拟机安装Linux系统(超详细)
目录 1.打开VMware虚拟机软件 2.选择Linux系统的ISO安装镜像 3.开启虚拟机安装系统 (1)进入Linux系统安装界面 (2)硬件检测 (3)检测光盘 (4)欢迎界面 (5)选择语言 ...