zoukankan      html  css  js  c++  java
  • Bogo Sort(2020牛客暑期多校五)

    Bogo Sort

    Problem:

    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 img with length img, and the algorithm's expectation complexity is (O(n cdot 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 imgwith length img, and he replaced the random shuffle with shuffle of img, so the improved algorithm, Tonnnny Sort, can solve sorting problems for length imgarray — 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 imgevery 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 (N, 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 imgdigits, so please output answer mod (10^N) instead.

    Input:

    The first line contains one integer (N (1 leq N leq 10^5)).

    The second line contains imginteger indicating img, which forms a permutation of (1, 2, cdots, N).

    Output:

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

    Example:

    Input

    5
    1 2 3 4 5
    

    Output

    1
    

    Input

    6
    2 3 4 5 6 1
    

    Output

    6
    

    题解:

    题意:对于一个置换序列有多少种排列可以通过若干次置换,变成1到n的排列。

    如果一个置换中没有环,则只有一种可能。

    如果一个置换中有一个环,且环长为3则可以找到三种排列。

    如果一个置换有两个环,且环长分别为2,则可以找到两种排列。

    归纳得出,对于一个长度为n的环可以得到n个原序列,当有多个环存在时,可以找出这些环长度的lcm,由于长度总和为n,所以lcm一定不会大于n位,所以不需要取模。

    Code:

    /**********************************************************
    * @Author: 			   Kirito
    * @Date:   			   2020-07-27 16:02:08
    * @Last Modified by:   Kirito
    * @Last Modified time: 2020-07-27 16:21:30
    * @Remark: 
    **********************************************************/
    #include <bits/stdc++.h>
    #define lowbit(x) (x&(-x))
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define INF 0x3f3f3f3f
    #define Abs(x) (x>=0?x:(-x))
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn=111111;
    int n,m,l,t,a[maxn],ans[maxn],prim[maxn],cyl[maxn],book[maxn],bp[maxn];
    
    void multi(int x)
    {
    	for(int i=1;i<=l;i++)
    		ans[i]*=x;
    	for(int i=1;i<l;i++)
    		if(ans[i]>9)
    			ans[i+1]+=ans[i]/10,ans[i]%=10;
    	while(l<n&&ans[l]>9){
    		ans[l+1]+=ans[l]/10;
    		ans[l++]%=10;
    	}
    	ans[l+1]=0;
    	return;
    }
    
    void getPrime()
    {
    	for(int i=2;i<=100000;i++){
    		if(bp[i]==0){
    			for(int j=i+i;j<=100000;j+=i){
    				bp[j]=1;
    			}
    			prim[++t]=i;
    		}
    	}
    	return;
    }
    
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	FAST;
    	getPrime();//获取范围内所有质数
    	ans[0]=0;ans[1]=1;l=1;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    		cin>>a[i];
    	//计算所有环的长度
    	for(int i=1;i<=n;i++){
    		if(book[i]) continue;
    		book[i]=cyl[++m]=1;
    		int be=a[i];
    		while(be!=i){
    			book[be]=1;
    			cyl[m]++;
    			be=a[be];
    		}
    	}
    	//对所有环的长度进行质因数分解,得到最后的lcm因子
    	CSE(bp,0);
    	for(int i=1;i<=m;i++){
    		for(int j=1;j<=t;j++){
    			if(cyl[i]<=1) break;
    			int num=0;
    			while(cyl[i]%prim[j]==0){
    				num++,cyl[i]/=prim[j];
    			}
    			bp[prim[j]]=max(bp[prim[j]],num);
    		}
    	}
    	//将所有因子相乘得到最终结果
    	for(int i=1;i<=t;i++)
    		while(bp[prim[i]]--)
    			multi(prim[i]);
    	for(int i=l;i>=1;i--)
    		cout<<ans[i];
    	return 0;
    }
    
  • 相关阅读:
    RTTI机制
    constexpr
    map/unordered_map
    Centos 安装Oracle
    JS带进度 文件 重复 自动 异步上传
    xadmin 小组件默认折叠
    xadmin datetime 类型报错 unsupported format characte
    Vmware 链接克隆 转 完整克隆 Converting a linked clone virtual machine to a full clone virtual machine
    vsftpd 530 500 553
    百度自然语言处理API调用
  • 原文地址:https://www.cnblogs.com/LeafLove/p/13386417.html
Copyright © 2011-2022 走看看