2020牛客暑期多校训练营(第五场)——E Bogo Sort

本文介绍了Bogo Sort的基本原理及其在牛客暑期多校训练营中的一道题目——E Bogo Sort。Tonnnny对Bogo Sort进行了改进,创建了Tonnnny Sort,它依赖于一个固定的最爱排列。文章详细阐述了输入输出格式,题目大意,并提供了题解思路和AC代码。

2020牛客暑期多校训练营(第五场)——E Bogo Sort

题目描述

Today Tonnnny the monkey learned a new algorithm called Bogo Sort. The teacher gave Tonnnny the code of Bogo sort:

bool is_sorted(int a[], int n) {
    for (int i = 1; i < n; i++) {
        if (a[i] < a[i - 1]) {
            return false;
        }
    }
    return true;
}
void bogo_sort(int a[], int n) {
    while (!is_sorted(a, n)) {
        shuffle(a, a + n);
    }
} 

The teacher said the shuffle function is to uniformly randomly permute the array a with length n, and the algorithm's expectation complexity is O(n⋅n!).However, Tonnnny is a determined boy — he doesn't like randomness at all! So Tonnnny improved Bogo Sort. He had chosen one favourite permutation p with length , and he replaced the random shuffle with shuffle of p, so the improved algorithm, Tonnnny Sort, can solve sorting problems for length N array — at least Tonnnny thinks so.

int p[N] = {....}; // Tonnnny's favorite permutation of n
void shuffle(int a[], int n) {
    int b[n];
    for (int i = 0; i < n; i++) {
        b[i] = a[i]
    }
    for (int i = 0; i < n; i++) {
        a[i] = b[p[i]];
    }
}

void tonnnny_sort(int a[], int n) {
    assert (n == N); // Tonnnny appointed!
    while (!is_sorted(a, n)) {
        shuffle(a, a + n);
    }
}

Tonnnny was satsified with the new algorithm, and decided to let you give him a different array of length N  every day to sort it with Tonnnny Sort.You are the best friend of Tonnnny. Even though you had found the algorithm is somehow wrong, you want to make Tonnnny happy as long as possible. You're given ,p and you need to calculate the maximum number of days that Tonnnny will be happy, since after that you can't give Tonnnny an array that can be sorted with Tonnnny Sort and didn't appeared before.The answer may be very large. Tonnnny only like numbers with at most N  digits, so please output answer mod 10^N instead.

输入描述

The first line contains one integer (1≤ 10^5).The second line contains  integer indicating p, which forms a permutation of 1,2,⋯,.

输出描述

The maximum number of days that Tonnnny will be happy, module 10^N.

输入

输入1

5
1 2 3 4 5

输入2

6
2 3 4 5 6 1

输出

输出1

1

输出2

6

题目大意

今天,Tonnnny学习了一种称为Bogo Sort的新算法。 老师给了Tonnnny Bogo Sort的代码:

bool is_sorted(int a[], int n) {
    for (int i = 1; i < n; i++) {
        if (a[i] < a[i - 1]) {
            return false;
        }
    }
    return true;
}
void bogo_sort(int a[], int n) {
    while (!is_sorted(a, n)) {
        shuffle(a, a + n);
    }
} 

 

老师说,函数shuffle 是等概率地随机排列长度为的数组a,这个算法的期望复杂度为O(n⋅n!)。

但是,Tonnnny是一个坚定的男孩——他一点也不喜欢随机! 因此,Tonnnny改进了Bogo Sort。 他选择了一个最喜欢的长度为的排列 p,然后用排列 替换随机的shuffle,因此改进的算法,Tonnnny Sort,可以解决长度为的数组的排序问题——至少Tonnnny如此认为。

 

int p[N] = {....}; // Tonnnny最喜欢的n的排列
void shuffle(int a[], int n) {
    int b[n];
    for (int i = 0; i < n; i++) {
        b[i] = a[i]
    }
    for (int i = 0; i < n; i++) {
        a[i] = b[p[i]];
    }
}

void tonnnny_sort(int a[], int n) {
    assert (n == N); // Tonnnny指定的
    while (!is_sorted(a, n)) {
        shuffle(a, a + n);
    }
}

Tonnnny对新算法感到满意,因此决定让您每天给他一个长度为N的不同数组,以使用Tonnnny Sort对其进行排序。

您是Tonnnny最好的朋友。 即使您发现该算法有某种错误,也希望让Tonnnny多快乐一会。 给定 和 p,您需要计算Tonnnny可以开心的最大天数,因为在那之后,您将不能给Tonnnny一个可以用Tonnnny Sort排序的之前没出现过的数组。

答案可能非常大。 Tonnnny只喜欢最多位的数字,因此请改为输出答案mod10^N

题解

所有环长度的 LCM。由于环长度总和是 n,所以一定不会大于 n 位数,不取模即可。 最长的答案也就几百位。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,l,r,cn=1,an,le=1,a[maxn],b[maxn],c[maxn],d[maxn],e[maxn],g[maxn],nu[maxn];
bool f[maxn];
void co(int x)
{
	for(int i=1;i<=le;i++)nu[i]*=x;
	for(int i=1;i<le;i++)if(nu[i]>9)nu[i+1]+=nu[i]/10,nu[i]%=10;
	while(le<n&&nu[le]>9)nu[le+1]+=nu[le]/10,nu[le++]%=10;
}
int main()
{
	nu[1]=1;
	for(int i=2;i<maxn;i++)if(!d[i]){for(int j=i*2;j<maxn;j+=i)d[j]=1;e[++an]=i;}
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		l=i,r=0;
		while(!f[l])f[l]=1,r=1,c[cn]++,l=a[l];
		if(r)cn++;
	}
	for(int i=0;i<cn;i++)
	{
		for(int j=1,t=0;j<an&&c[i]>1;j++)
		{
			while(c[i]%e[j]==0)t++,c[i]/=e[j];
			b[e[j]]=max(b[e[j]],t);t=0;
		}
	}
	for(int i=1;i<=an;i++)while(b[e[i]]--)co(e[i]);
	for(int i=le;i>=1;i--)printf("%d",nu[i]);
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值