首页 > 其他分享 >康托展开

康托展开

时间:2022-10-16 16:57:00浏览次数:55  
标签:排列 int ll ans 展开 fact 康托

康托展开

康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩。设有n个数(1,2,3,4,...,n) ,可以有组成不同(n!种)的排列组合,康托展开表示的就是是当前排列组合在n个不同元素的全排列中的名次。也就是说,康托展开可以用来求一个 的任意排列的排名。

他的具体原理也不复杂,不过没啥用,不浪费时间展开说明,感兴趣百度有很多优秀的解释。

这里直接给出他的模板代码。暴力O(n^2),树状数组优化可以做到O(nlogn).但是求排列,一般n不会很大。

所以大部分情况暴力就能解决问题。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll fact[1010],P[1010],A[1010],tree[1010];//P是排列数组,fact是阶乘,自己初始化
ll lowbit(ll x)
{ 
    return x&-x; 
}
ll query(ll x)
{
    ll ans = 0;
    for (int i = x; i >= 1; i -= lowbit(i))
        ans += tree[i];
    return ans;
}
void update(ll x, ll d)
{
    for (int i = x; i <1010; i += lowbit(i))
        tree[i] += d;
}
ll cantor(int P[], int n)
{
    ll ans = 1;
    for (int i = n; i >= 1; i--)
    {
        A[i] = query(P[i]);
        update(P[i], 1);
    }
    for (int i = 1; i < n; i++)
        ans = (ans + A[i] * fact[n - i]) % MOD;
    return ans;
}
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    
    return 0;
}

逆康托展开

其实就是把康托展开的过程反过来,给你排名,让你求出这个排名对应的排列。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll fact[MAXN] = {1}, P[MAXN],A[MAXN]; //fact需要在外部初始化
void decanter(ll x,ll n) //x为排列的排名,n为排列的长度
{
    x--;
    vector<int> rest(n, 0);
    iota(rest.begin(), rest.end(), 1); //将rest初始化为1,2,...,n
    for (int i = 1; i <= n; ++i)
    {
        A[i] = x / fact[n - i];
        x %= fact[n - i];
    }
    for (int i = 1; i <= n; ++i)
    {
        P[i] = rest[A[i]];
        rest.erase(lower_bound(rest.begin(), rest.end(), P[i]));
    }
}

标签:排列,int,ll,ans,展开,fact,康托
From: https://www.cnblogs.com/tscjj/p/16796521.html

相关文章

  • Visual Studio扩展开发——清理实验环境
    清理实验环境如果您正在开发多个扩展,或者只是使用不同版本的扩展代码来探索结果,那么您的实验环境可能会停止按应有的方式工作。在这种情况下,您应该运行重置脚本。它称为重......
  • 114. 二叉树展开为链表
    题目描述给你二叉树的根结点root,请你将它展开为一个单链表:展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。展......
  • el-pagination size下拉框展开时页面出现双层滚动条问题
    由于项目中给内容区域设置了单独的滚动条,无需body出现滚动条,当分页选项的下拉框展开时,出现了双层滚动条的效果不展开时的滚动条效果:  展开时的滚动条效果   ......
  • element 树结构 一键展开
     <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"con......
  • 根据百分比展开员工行
    问题:左表为“序号与企业名称表”,右表为“百分比表”,根据F列的百分比,扩展E列员工,效果如C列。两个表均加载到PQ管理器内,以下M在“百分比表”中。let源=Excel.Curre......
  • IDEA 项目视图保存节点展开状态
    没兴趣看过程的,请直接跳转到「解决方案」部分。问题现象IDEA折叠再展开之后,之前展开的状态就没有了(若gif未自动播放,可在新标签页打开):不像Eclipse可以保存展开状......
  • 常见的泰勒展开
    常见的泰勒展开目录常见的泰勒展开【1】☆☆☆e的x次方【2】☆☆☆sinx【3】☆☆☆1-x分之1【4】cosx【5】1+x分之1【6】ln(1+x)【7】1+x方分之1【8】arcta......
  • vscode 折叠ctrl+k, ctrl+0 展开ctrl +k, ctrl+J
    vscode代码编辑器折叠所有区域的代码快捷键(1)折叠所有区域代码的快捷键:ctrl+k,ctrl+0;​先按下ctrl和K,再按下ctrl和0;(注意这个是零,不是欧)(2)展开所有折叠区域代码的快捷......
  • leetcode 144. Binary Tree Preorder Traversal 二叉树展开为链表(中等)
    一、题目大意给你二叉树的根节点root,返回它节点值的前序遍历。示例1:输入:root=[1,null,2,3]输出:[1,2,3]示例2:输入:root=[]输出:[]示例3:输入:root=......
  • DevExpress列表取消右键折叠展开菜单
    DevExpress版本升级后,以前的右键菜单不再弹出了,替代变成了系统自带的折叠、展开菜单。解决方法:在OptionsMenu中将ShowExpandCollapseltems设置为False即可。......