Codeforces843A 思维(伪并查集

题意:给你一串n个数的序列 你可以把这个序列分成任意个序列 且要满足分成的每个子序列重新排序后再放回原来的对应位置 原序列有序
思路:就是模拟一下整个过程,(和找并查集有点类似)
首先因为数范围很大,总数量不大,所以离散化,因为没有相等的 所以不用去重。
自然而然的,离散化之后的序列就是1~n的n个数
所以我们要做的就是:
对于当前的数组,扫一遍,对于每个元素:
若这个元素的值等于它的坐标,这个元素单独分一个序列
如果这个元素的值不等于它的坐标,(而这个值最后是要排到当前值的坐标的),所以令p=a[a[p]] 然后直到p==a[i]就停下 把这个过程中的所有元素放成一组
最后还要给vector排个序
下面是ac代码:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define cl(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define dbg() printf("aaa\n")
using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn],acopy[maxn];
vector<int> g[maxn];
bool con[maxn];
bool sortFun(const int &p1, const int &p2){
	return p1<p2;//升序排列  
}
int main() {
	sd(n);
    rep(i,1,n) sd(a[i]);
    rep(i,1,n) acopy[i]=a[i];
    sort(acopy+1,acopy+n+1);//不用unique去重!
    rep(i,1,n){//离散化
        con[i]=false;
        a[i]=lower_bound(acopy+1,acopy+n+1,a[i])-acopy;
    }
    int k=0;
    rep(i,1,n){//对于所有元素
        if(con[i]) continue;
        if(a[i]==i) {
            g[++k].push_back(i);
            con[i]=true;
        }
        else{
            g[++k].push_back(i);
            con[i]=true;
            int tp=a[i],p=i;
            while(1){
                p=tp;
                tp=a[p];
                con[p]=true;
                if(p!=g[k][0]) g[k].push_back(p);
                else break;
            }
        }
    }
    printf("%d\n",k);
    rep(i,1,k){
        printf("%d",g[i].size());
        sort(g[i].begin(),g[i].end(),sortFun);
        rep(j,0,g[i].size()-1)
            printf(" %d",g[i][j]);
        putchar('\n');
    }

	return 0;
}

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

发布了120 篇原创文章 · 获赞 12 · 访问量 5275

猜你喜欢

转载自blog.csdn.net/weixin_43735161/article/details/104630244
今日推荐