LGP6305题解
作者:互联网
笑死,细节问题直接把自己送走了,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