ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LGP6305题解

2022-09-12 16:32:14  阅读:145  来源: 互联网

标签:10 putchar LGP6305 int 题解 write const include


笑死,细节问题直接把自己送走了,100pts->0pts。

个人认为是模拟赛最简单的一道题 可能是因为我倒开

如果 \(a\) 中元素互不相同很好做,排序然后变成 \(i\) 应该去到 \(p_i\) 的位置,直接连接 \((i,p_i)\) 然后输出每个环即可。

但是可能出现不相同的元素。

考虑对于排序后的序列,一段区间 \([L,R]\) 满足权值相等,并记 \(q[i]\) 为 \(p\) 的逆置换。(也就是谁要到这里来)

然后会发现,这些 \(q\) 有可能互相不属于相同的环,但是显然可以通过令 \(q[i]\) 连接 \(i+1\)(\(i=R\) 特判)来做到变为一个环。

然后还需要注意的是,实际上可以花费 \(s\) 的代价,将 \(s\) 个环拼接在一起,然后再加一次操作。

具体来讲就是像上面一样把环混在一起,然后交换哪些不正确的位置,样例 \(4\) 有体现这个。

剩下的就是细节了,复杂度 \(O(n\log n)\),排序和并查集即可。

#include<algorithm>
#include<cstdio>
#include<cctype>
#include<vector>
namespace SOLVE{
	const int M=2e5+5;
	int n,m,s,len,f[M],a[M],b[M],p[M],t[M],id[M];bool vis[M];std::vector<int>q[M];
	inline int read(){
		int n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
	}
	inline void write(int n){
		static char s[15];int top(0);while(s[++top]=n%10^48,n/=10);while(putchar(s[top]),--top);
	}
	inline int Find(const int&u){
		return f[u]==u?u:f[u]=Find(f[u]);
	}
	inline void main(){
		n=read();s=read();for(int i=1;i<=n;++i)b[i]=a[i]=read();std::sort(b+1,b+n+1);
		for(int i=1;i<=n;++i)if(a[i]!=b[i])id[++len]=i,t[len]=i;if(len>s)return printf("-1"),void();
		std::sort(id+1,id+len+1,[&](const int&x,const int&y){return a[x]==a[y]?x<y:a[x]<a[y];});
		for(int i=1;i<=len;++i)p[id[i]]=t[i];s-=len;
		for(int i=1;i<=n;++i)if(!f[i]&&a[i]!=b[i]){
			int j=i;do f[j]=i;while((j=p[j])^i);
		}
		for(int R,L=1;L<=len;L=R+1){
			for(R=L;R<len&&a[id[R+1]]==a[id[L]];++R);vis[Find(id[L])]=true;
			static int m,x[M],y[M];m=1;x[m]=id[L];y[m]=t[L];
			for(int i=L+1;i<=R;++i)if(!vis[Find(id[i])])++m,x[m]=id[i],y[m]=t[i],vis[Find(id[i])]=true;
			if(m^1)for(int i=1;i<=m;++i)p[x[i]]=y[i==m?1:i+1];for(int i=2;i<=m;++i)f[Find(x[i])]=Find(id[L]);
			vis[Find(id[L])]=false;
		}
		int cnt(0);for(int i=1;i<=n;++i)vis[i]=false;
		for(int i=1;i<=n;++i)if(a[i]!=b[i]&&!vis[i]){
			int j=i,cnt(0);do++cnt,vis[j]=true;while((j=p[j])^i);++m;
			j=i;do q[m].push_back(j);while((j=p[j])^i);
		}
		if(s>m)s=m;
		if(!m)write(0);
		else if(m==1){
			write(1);putchar(10);write(q[1].size());putchar(10);for(int&w:q[1])write(w),putchar(32);
		}
		else if(s<=1){
			write(m);putchar(10);
			for(int i=1;i<=m;++i){
				write(q[i].size());putchar(10);for(int&w:q[i])write(w),putchar(32);putchar(10);
			}
		}
		else{
			int sum(0);
			for(int i=1;i<=s;++i)sum+=q[i].size();write(m-s+2);putchar(10);
			write(sum);putchar(10);for(int i=1;i<=s;++i)for(int&w:q[i])write(w),putchar(32);putchar(10);
			write(s);putchar(10);for(int i=s;i>=1;--i)write(*q[i].begin()),putchar(32);putchar(10);
			for(int i=s+1;i<=m;++i){
				write(q[i].size());putchar(10);for(int&w:q[i])write(w),putchar(32);putchar(10);
			}
		}
	}
}
signed main(){
	SOLVE::main();
}

标签:10,putchar,LGP6305,int,题解,write,const,include
来源: https://www.cnblogs.com/lmpp/p/16686480.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有