CF #319 div 2 D

这道题算不算脑洞题。。

可以发现,当一个排列中有循环节时长度为1或2时可能有解。当为1时,只需把全部点都连到这个题即可,当为2时,就要求所有循环节长度均为偶数,这很容易理解,因为如果存在为奇数,它们之间连线之后就可以形成环或者不存在的情况了。把其他循环节上的点分别连到这两个点上即可。为什么是2呢?因为,可以理解为树上的一条连连T_T

666666

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;

int permutations[100005];
bool vis[100005];
vector<int>ans;

int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<=n;i++){
			scanf("%d",&permutations[i]);
			memset(vis,false,sizeof(vis));
		}

		bool one_exist=false;
		bool two_exist=false;
		int two_pos=-1;
		int ans_one=-1;
		ans.clear();
		for(int i=1;i<=n;i++){
			if(!vis[i]){
				int cc=1;
				vis[i]=true;
				int ni=i;
				while(!vis[permutations[ni]]){
					ni=permutations[ni];
					vis[ni]=true;
					cc++;
				}
				if(cc==1){
					one_exist=true;
					ans_one=i;
					break;
				}
				if(cc==2){
					two_exist=true;
					two_pos=i;
				}
				ans.push_back(cc);
			}
		}

		int sz=ans.size();
		if(one_exist){
			puts("YES");
			for(int i=1;i<=n;i++){
				if(i!=ans_one){
					printf("%d %d\n",ans_one,i);
				}
			}
			continue;
		}

		if(two_exist){
			bool flag=true;
			for(int i=0;i<sz;i++){
				if(ans[i]%2!=0){
					flag=false;
					break;
				}
			}
			if(flag){
				puts("YES");
				printf("%d %d\n",two_pos,permutations[two_pos]);
				vis[two_pos]=false;
				vis[permutations[two_pos]]=false;
				for(int i=1;i<=n;i++){
					if(vis[i]){
						int counts=0;
						vis[i]=false;
						int ni=i;
						printf("%d %d\n",two_pos,ni);
						while(vis[permutations[ni]]){
							if(counts&1){
								counts^=1;
								printf("%d %d\n",permutations[ni],two_pos);
							}
							else{
								counts^=1;
								printf("%d %d\n",permutations[two_pos],permutations[ni]);
							}
							vis[permutations[ni]]=false;
							ni=permutations[ni];
						}
					}
				}
				continue;
			}
		}

		puts("NO");
	}
	return 0;
}
时间: 2024-10-21 01:32:14

CF #319 div 2 D的相关文章

cf 319 div 2 Modulo Sum 数论+DP

 Modulo Sum 题目抽象:给你你一个整数数组,能否从中取出一些树,使得他们的和能被m整除. 分析:见代码注释. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int MS = 1000005; 5 int n, m; 6 int cnt[MS], r[MS], tem[MS]; 7 int main() { 8 scanf("%d%d", &n, &

CF #319 div 2 E

在一个边长为10^6正方形中,可以把它x轴分段,分成1000段.奇数的时候由底往上扫描,偶数的时候由上往下扫描.估计一下这个最长的长度,首先,我们知道有10^6个点,则y邮方向最多移动10^3*10^6.对于x轴方向,如果都在一个段内,则最多移动 10^3*10^6,如果均不在一个段内,最多就2000*10^3.比限制长度肯定要小. #include <iostream> #include <cstdio> #include <algorithm> using name

CF #371 (Div. 2) C、map标记

1.CF #371 (Div. 2)   C. Sonya and Queries  map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的匹配. #include<bits/stdc++.h> #define max(a,b) a>b?a:b #define F(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF

CF#247(Div. 2)部分题解

引言: 在软件项目中,Maven提供了一体化的类库管理系统,非常实用.但是,如果新增的类库jar在网络上无法获取到,如何在本地按照Maven的规则添加进来呢?本文将通过一个小例子展示新增过程. 背景介绍: 一个Maven管理的Java项目,提供一个系统级别的POM.xml,其中定义了整个项目使用的类库. 需求: 需要添加一个自定义的类库到当前项目中.假定当前的类库文件名为:abc.jar.. 如何将类库添加进来? 1.  找到当前Maven的Repository类库位置 一般默认情况下,在win

CF #375 (Div. 2) D. bfs

1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多少个湖,然后输出. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,s

Codeforces Round #319 (Div. 2) C Vasya and Petya&#39;s Game

因为所有整数都能被唯一分解,p1^a1*p2^a2*...*pi^ai,而一次询问的数可以分解为p1^a1k*p2^a2k*...*pi^aik,这次询问会把所有a1>=a1k && a2 >= a2k &&... a3 >= a3k的数从原来的集合中分开.ai表示pi的幂. 那么只有当这个数的素因子的最大幂都被询问过一次,这个数才能确定.因此答案是所有的不大于n的只有一个素因子的数. #include<bits/stdc++.h> using

CF #374 (Div. 2) D. 贪心,优先队列或set

1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优先队列 #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(

cf #254 (Div. 2)

a题 #include<stdio.h> #include<string.h> char c[101][101]; int main() { long n,m,i,j; scanf("%ld%ld",&n,&m); gets(c[0]); for(i=1;i<=n;i++) gets(c[i]); for(i=1;i<=n;i++) { for(j=0;j<m;j++) if(c[i][j]=='-') printf("

B. Mr. Kitayuta&#39;s Colorful Graph (CF #286 (Div. 2) 并查集)

B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the g