CF 843A Sorting by Subsequences

原题走这里

题目大致意思就是,给定一个数组,求出最多能把数组分成多少个子序列,使得各个子序列分别排序后能使整个数组有序

记住是子序列子序列子序列重要的事情说三遍

第一行输出个数,接下来n行输出n个子序列

每行第一个数是子序列的长度,之后才是序列


仔细观察之后发现,我们可以将题目给定的无序数组,视作排序后数组的一个置换

而题目中符合要求的一个子序列,就是原置换循环分解产生的其中一个置换

因此,我们只需要求出原置换能够循环分解产生多少个置换即可

只要想到这一点题目就很简单了


例如样例中的3 2 1 6 5 4

可以写成1 2 3 4 5 6的一个置换

循环分解成(1,3)(2)(4,6)(5)总共4个置换,对应四个子序列

于是答案便是4


代码如下

#include <bits/stdc++.h>
using namespace std;
int n,j,a[100010],A[100010];
bool b[100010];
vector<int> v[100010];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",a+i);
		A[i]=a[i];
	}	
	sort(A+1,A+n+1);
	for(int i=1;i<=n;i++)
	{
		if(b[i])continue;
		j++;
		for(int k=i;!b[k];k=lower_bound(A+1,A+n+1,a[k])-A)
		{
			v[j].push_back(k);
			b[k]=1;
		}
		sort(v[j].begin(),v[j].end());
	}
	printf("%d\n",j);
	for(int i=1;i<=j;i++)
	{
		printf("%d",v[i].size());
		for(int k=0,len=v[i].size();k<len;k++)
		{
			printf(" %d",v[i][k]);	
		}
		printf("\n");
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值