• 康托展开和逆康托展开


    为什么我在EN-WIKI上查不到啊TAT

    嗯,康托展开就是一个从n排列集合到自然数集合的映射.

    并且这个映射刚好对应了字典序.

    比如,设这个函数为C,

    那么C{1,2,3}=0,C{3,2,1}=5,C{2,3,1}=3.

    用于排列与数字的转换.


    使用的时候一定要注意先把排列离散化成0,1,...,n-1的排列再做.

    否则要用n^2的时间来找"在全集中比数i小的数个数." 离散化以后直接就是a[i]+1就好做一些.


    离散化之后可以用树状数组或者线段树或者平衡树做到nlogn.


    #include <cstdio>
    #include <iostream>
    #include <fstream>
    
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef unsigned int uint;
    typedef double db;
    
    int getint()
    {
    	int res=0; char c=getchar(); bool m=false;
    	while(c<'0' || c>'9') m=(c=='-'),c=getchar();
    	while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
    	return m ? -res : res;
    }
    
    const db eps=1e-18;
    bool feq(db a,db b)
    { return fabs(b-a)<eps; }
    
    using namespace std;
    
    
    
    
    int a[50]={0,1,2,3,4,5};
    
    int getpow(int i)
    {
    	int res=1;
    	while(i>0) res*=i,i--;
    	return res;
    }
    
    int Cantor(int*a,int n)
    {
    	int res=0;
    	for(int i=0;i<n;i++)
    	{
    		int cnt=0;
    		for(int j=0;j<i;j++) if(a[j]<a[i]) cnt++;
    		res+=getpow(n-i-1)*max(0,a[i]-cnt);
    	}
    	return res;
    }
    
    bool used[50];
    int*RevCantor(int X,int n)
    {
    	int*res=new int[n+1];
    	
    	memset(used,0,sizeof(bool)*(n+1));
    	for(int i=0;i<n;i++)
    	{
    		int p=X/getpow(n-i-1);
    		X=X-p*getpow(n-i-1);
    		
    		int j=0;
    		for(;used[j]||p>0;j++)
    		if(!used[j]) p--;
    		
    		res[i]=j;
    		used[j]=true;
    	}
    	
    	return res;
    }
    
    int main()
    {
    	for(int i=0;i<10;i++)
    	{
    		int c=Cantor(a,6);
    		cout<<i<<' '<<c<<endl;
    		for(int i=0;i<6;i++) cout<<a[i]<<' '; cout<<endl;
    		next_permutation(a,a+6);
    		int*p=RevCantor(c,6);
    		for(int i=0;i<6;i++) cout<<p[i]<<' '; cout<<endl;
    		delete(p);
    	}
    	
    	
    	return 0;
    }
    

  • 相关阅读:
    使用express框架创建服务器
    搭建第一个node服务器
    Node 与JS的区别
    node学习之路
    【每天一个linux命令】read
    【每天一个linux命令】awk
    【每天一个linux命令】wc
    【每天一个linux命令】sed
    【每天一个linux命令】tee
    【每天一个linux命令】find
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4295944.html
Copyright © 2020-2023  润新知