CF C. Sorting by Subsequences AIM Tech Round 4 (Div. 2)(简单模拟)

来源:互联网 发布:刷贴软件 编辑:程序博客网 时间:2024/06/01 20:33

You are given a sequence a1, a2, …, an consisting of different integers. It is required to split this sequence into the maximum number of subsequences such that after sorting integers in each of them in increasing order, the total sequence also will be sorted in increasing order.

Sorting integers in a subsequence is a process such that the numbers included in a subsequence are ordered in increasing order, and the numbers which are not included in a subsequence don’t change their places.

Every element of the sequence must appear in exactly one subsequence.

Input
The first line of input data contains integer n (1 ≤ n ≤ 10^5) — the length of the sequence.

The second line of input data contains n different integers a1, a2, …, an ( - 10^9 ≤ ai ≤ 10^9) — the elements of the sequence. It is guaranteed that all elements of the sequence are distinct.

Output
In the first line print the maximum number of subsequences k, which the original sequence can be split into while fulfilling the requirements.

In the next k lines print the description of subsequences in the following format: the number of elements in subsequence ci (0 < ci ≤ n), then ci integers l1, l2, …, lci (1 ≤ lj ≤ n) — indices of these elements in the original sequence.

Indices could be printed in any order. Every index from 1 to n must appear in output exactly once.

If there are several possible answers, print any of them.

Examples

input
6
3 2 1 6 5 4
output
4
2 1 3
1 2
2 4 6
1 5

input
6
83 -75 -49 11 37 62
output
1
6 1 2 3 4 5 6

Note
In the first sample output:

After sorting the first subsequence we will get sequence 1 2 3 6 5 4.

Sorting the second subsequence changes nothing.

After sorting the third subsequence we will get sequence 1 2 3 4 5 6.

Sorting the last subsequence changes nothing.

大致题意:给你一个正整数序列,里面的数各不相同,然后让你将他们分成若干个子序列,分别对其进行排序(比如你选了1,3,5这三个位置作为一个子序列那么排序就在这三个位置上进行),使得排序完的子序列组成的序列和原来序列排完序的相同,问最多能分成多少个子序列,输出每个子序列所包含的元素,每个元素只能出现一次。

思路:当某个位置x上的数排完序后依旧在这个位置上,那么就可以直接选它作为一个子序列。否则假设排序完后它的位置为y,那么我们需要将y位置上的数加入到子序列中,然后再看y位置上的数排完序后的位置是哪个,重复上面的操作,直到这个子序列构成一个环。然后答案就是所能构成环的最多的数量。

代码如下

#include<iostream>#include<algorithm>#include<string>#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<cstring>using namespace std;const int maxn=1e5+5;int n;int vis[maxn];//判断某个位置是否已经选取vector<int> ans[maxn];//保存第i个子序列中所选的位置struct node {    int num;//数值    int wei;//位置};node a[maxn];bool cmp(node x,node y){    return x.num<y.num;}int main()  {      memset(vis,0,sizeof(vis));    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i].num);        a[i].wei=i;    }    sort(a+1,a+1+n,cmp);    int k=0;//记录构成环的数量    for(int i=1;i<=n;i++)    {        if(!vis[i])        {            int p=i;            while(!vis[p])            {                vis[p]=1;                   ans[k].push_back(a[p].wei);                p=a[p].wei;            }            k++;        }    }    cout<<k<<endl;    for(int i=0;i<k;i++)    {        cout<<ans[i].size();        for(int j=0;j<ans[i].size();j++)        cout<<' '<<ans[i][j];        cout<<endl;    }    return 0;  }  
原创粉丝点击