一、关于康托展开

1.什么是康托展开

求出给定一个由1n个整数组成的任意排列在1n的全排列中的位置。

解决这样问题的算法叫康托展开。

例如:

\(n=4\),序列a={\(1,3,4,2\)},那么a在1~4中的全排列位置为第4个。

2.康托展开实现原理

要知道序列a排在第几位,我们就需要知道序列a之前有多少位。

我们按照上面的栗子计算:

1.比1小的数有0个,有\(0\times(4-1)!=0\)种排列。

2.比3小的数有2个,但是1已经被占用了,因此可用只有1个数,共有\(1\times(3-1)!=2\)种排列。

3.比4小的数有3个,但是1,3被占用,可用的数字只有1个,共有\(1\times(2-1)!=1\)种排列。

4.比2小的数有一个,但是全被占用了,因此可用排列为\(0\times(1-1)!=0\)。

到现在为止,我们知道在序列a前面的排列有3个,因此序列a排在第4位。

公式:

\[pos=k_1(n-1)!+k_2(n-2)!+...+k_n(n-n)!
\]

统计时使用树状数组优化,总复杂度为\(O(NlogN)\)。

二、具体实施

1.模板

P5367 【模板】康托展开

#include<bits/stdc++.h>
#define ll long long
#define N 1000010
#define MOD 998244353
using namespace std;
int n,t[N];
ll fac[N],ans;
inline void calc_factorial(int n){
fac[1]=1;
for(int i=2;i<=n;i++)
fac[i]=i*fac[i-1]%MOD;
}
inline int lowbit(int x){
return x&(-x);
}
inline void modify(int x,int k){
while(x<=n){
t[x]+=k;
x+=lowbit(x);
}
}
inline ll query(int x){
ll res=0;
while(x>0){
res+=t[x];
x-=lowbit(x);
}
return res;
}
int main()
{
scanf("%d",&n);
calc_factorial(n);
for(int i=1;i<=n;i++) modify(i,1);
for(int i=1,num;i<=n;i++){
scanf("%d",&num);
ans=(ans+((query(num)-1)*fac[n-i])%MOD)%MOD;
//core code: restnum*(n-i)!
modify(num,-1);
}
printf("%lld",ans+1);
return 0;
}

[算法总结]康托展开Cantor Expansion的更多相关文章

  1. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  2. BZOJ3301 P2524 UVA11525 算法解释康托展开

    这三个题的代码分别对应第二个第一个第三个 在刘汝佳蓝书上我遇到了这个康托展开题. 当时去了解了一下,发现很有意思 百度上的康托展开定义 原理介绍 编辑 康托展开运算 其中, 为整数,并且 . 的意义为 ...

  3. 【算法进阶-康托展开】-C++

    目录 引入 这位老爷子就是康托 基本概念 康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩.设有n个数(1,2,3,4,-,n),可以有组成不同(n!种)的排列组合,康托展开表 ...

  4. 康托展开+逆展开(Cantor expension)详解+优化

    康托展开 引入 康托展开(Cantor expansion)用于将排列转换为字典序的索引(逆展开则相反) 百度百科 维基百科 方法 假设我们要求排列 5 2 4 1 3 的字典序索引 逐位处理: 第一 ...

  5. 康托展开&逆展开算法笔记

    康托展开(有关全排列) 康托展开:已知一个排列,求这个排列在全排列中是第几个 康托展开逆运算:已知在全排列中排第几,求这个排列 定义: X=an(n-1)!+an-1(n-2)!+...+ai(i-1 ...

  6. 康托(Cantor)展开

    直接进入正题. 康托展开 Description 现在有"ABCDEFGHIJ”10个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? Input ...

  7. 洛谷P2525 Uim的情人节礼物·其之壱 [康托展开]

    题目传送门 Uim的情人节礼物·其之壱 题目描述 情人节到了,Uim打算给他的后宫们准备情人节礼物.UIm一共有N(1<=N<=9)个后宫妹子(现充去死 挫骨扬灰!). 为了维护他的后宫的 ...

  8. HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】

    一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...

  9. hihoCoder #1312 : 搜索三·启发式搜索(A*, 康托展开)

    原题网址:http://hihocoder.com/problemset/problem/1312 时间限制:10000ms 单点时限:1000ms 内存限制:256MB   描述 在小Ho的手机上有 ...

随机推荐

  1. Unity 游戏框架:UI 管理神器 UI Kit

    UI Kit 快速入门 首先我们来进行 UI Kit 的快速入门 制作一个界面的,步骤如下: 准备 生成代码 逻辑编写 运行 1. 准备 先创建一个场景 TestUIHomePanel. 删除 Hie ...

  2. ASP.NET Core 核心特性--宿主、启动、中间件

    宿主 public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().R ...

  3. Python第七章-面向对象高级

    面向对象高级 一. 特性 特性是指的property. property这个词的翻译一直都有问题, 很多人把它翻译为属性, 其实是不恰当和不准确的. 在这里翻译成特性是为了和属性区别开来. 属性是指的 ...

  4. Oracle 10g客户端的安装和配置

    1.双击Oracle11g_database安装目录下的Setup.exe. 2.选择“基本安装”,设置“安装位置”,填写“数据库名”和“口令”,点击“下一步”. 3.点击“下一步”. 4.一般会出现 ...

  5. A. Remainder Codeforces Round #560 (Div. 3)

    A. Remainder Codeforces Round #560 (Div. 3) You are given a huge decimal number consisting of nn dig ...

  6. Girls' research(马拉车算法) hdu 3294

    文章目录 思路如下 Manachar代码注释 题解如下 Problem Description One day, sailormoon girls are so delighted that they ...

  7. Ali_Cloud++:阿里云部署 Jenkins持续集成自动化部署

    安装方式: 1.yum 源安装 rpm包 2.结合 tomcat 使用 war包 ....... 下载地址:Dowlnoad  (分:长期支持版本 (LTS)  和  每周更新版) jenkins插件 ...

  8. JavaScript简单使用

    本文参考廖雪峰老师网站:https://www.liaoxuefeng.com/wiki/1022910821149312 JavaScript是一种运行在浏览器中的解释型的编程语言,在Web世界里, ...

  9. JS数据结构与算法 - 二叉树(一)基本算法

    仅供JavaScript刷题参考用. 二叉查找树和平衡二叉树 其它树:满二叉树.完全二叉树.完美二叉树.哈弗曼树.二叉查找树BST.平衡二叉树AVL 了解:红黑树,是一种特殊的二叉树.这种树可以进行高 ...

  10. NAT及静态转换,动态转换及PAT

    NAT及静态转换,动态转换及PAT 案例1:配置静态NAT 案例2:配置端口映射 案例3:配置动态NAT 案例4:PAT配置 案例5:办公区Internet的访问 1 案例1:配置静态NAT 1.1 ...