Sorting by Subsequences CodeForces - 844C

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 ≤ 105) — the length of the sequence.

The second line of input data contains n different integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — 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 ciintegers 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.

Example
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.



emmm..不看题解完全不知道这个题要干啥..

就是把序列分成几份,每一份内排序,最后放在一起就是一个排好序的队列。要求每个位置都要被选到一次。

比如明明选择序列1到3可以排好1-3的顺序。但是2你还要单独选择一次。

这道题就是准备两个数组,一个是原序列,一个事排好序的序列。

对于排好序的第一个位置,我们看看这个数在原序列是什么位置,代表1-那个位置算做一组。我们不停地dfs直到

找不到了,这一系列找到的都是算做同一组的,因为一环套一环。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<vector>
using namespace std;
int a[110000];
int b[110000];
int vis[110000];
int n;
int cnt;
vector<int>shuchu[110000];
map<int,int>mp;
void dfs(int dangqian,int dijige)
{
    shuchu[dijige].push_back(dangqian);
    vis[dangqian]=1;
    int mubiao=mp[a[dangqian]];//当前位置上的数字原本是啥,而排序后在哪个位置
      //从当前位置到那个位置我们要放在一个桶中
    if(!vis[mubiao])//如果那个位置的数没有访问到
    {
        dfs(mubiao,dijige);//继续访问
    }
}
int main()
{
    while(cin>>n)
    {


        cnt=0;


        mp.clear();
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            b[i]=a[i];
            shuchu[i].clear();
        }
        sort(b+1,b+1+n);
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            mp[b[i]]=i;//某个数出现在那个位置
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i])
            {
               continue;
            }
            else
            {
                dfs(i,cnt);
                cnt++;
            }
        }
        cout<<cnt<<endl;
        for(int i=0;i<cnt;i++)
        {
            cout<<shuchu[i].size();
            for(int j=0;j<shuchu[i].size();j++)
            {
                cout<<" "<<shuchu[i][j];
            }
            cout<<endl;
        }


    }
}。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值