一、关于康托展开

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. 如何编写shellcode

    ShellCode的编写就是将函数或变量在内存中的间接地址改为函数或变量在内存中的直接地址,直接调用! 以MessageBox函数为例进行讲解如下 新建shellcode.cpp: 编写代码如下: 运 ...

  2. 第十八周java实验作业

    实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...

  3. JSP(一)----入门学习

    ##  JSP 1.概念: *  Java  Server  Pages:java服务端页面 *  可以理解为:一个特殊的页面,其中既可以直接定义html标签,又可以定义java代码 2.原理 *  ...

  4. [dfs] HDU 2019 Multi-University Training Contest 10 - Block Breaker

    Block Breaker Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)T ...

  5. 3.Scikit-Learn实现完整的机器学习项目

    1       完整的机器学习项目 完成项目的步骤: (1)    项目概述 (2)    获取数据 (3)    发现并可视化数据,发现规律. (4)    为机器学习算法准备数据. (5)    ...

  6. Building Applications with Force.com and VisualForce (DEV401) (二二):Visualforce Componets (Tags) Library Part II

    Dev401-023:Visualforce Pages: Visualforce Componets (Tags) Library Part II   Apex:pageBlockTable1.A ...

  7. 干货|Python基础入门 课程笔记(三)

    目录 列表 元组 字典 三元表达式 一.列表 前面学习的字符串可以用来存储一串信息,那么想一想,如果现在有很多人,总不能每个人都起一个变量名把?那岂不得疯~ 咱们可以使用列表. (1)列表得格式和输出 ...

  8. mongodb的增加和删除

    一  mongodb中使用insert()方法来增加集合中的文档: db.myTable.insert({name:'arvin',age:12}) //对名为myTable的集合插入数据 插入数据 ...

  9. JS 剑指Offer(四) 从尾到头打印链表

    题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...

  10. Codeforces 631 (Div. 2) D. Dreamoon Likes Sequences 位运算^ 组合数 递推

    https://codeforces.com/contest/1330/problem/D 给出d,m, 找到一个a数组,满足以下要求: a数组的长度为n,n≥1; 1≤a1<a2<⋯&l ...