P5367 【模板】康托展开

感觉这题难度大概在绿题到蓝题之间qwq

一、洛谷日报[yummy]浅谈康托展开

如我想知道321是{1,2,3}中第几个小的数可以这样考虑 :

第一位是3,当第一位的数小于3时,那排列数小于321 如 123、 213 ,小于3的数有1、2 。所以有2× 2!个。再看小于第二位2的:小于2的数只有一个就是1 ,所以有1× 1!=1 所以小于321的{1,2,3}排列数有2×2!+1×1!=5个。所以321是第6个小的数。 2 ×2!+1× 1!+0× 0!就是康托展开。

再举个例子:1324是{1,2,3,4}排列数中第几个大的数:第一位是1小于1的数没有,是0个 0× 3! 第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2,1×2! 。第三位是2小于2的数是1,但1在第一位,所以有0个数 0×1! ,所以比1324小的排列有0×3!+1× 2!+0×1 !=2个,1324是第三个小数。(摘自百度)

暴力做法

//n表示全排列长度
for(int i=1;i<=n;i++)
{
cin>>a[i];
int x=a[i];
for(int j=1;j<=a[i];j++)
x-=used[j];
//used[j]表示j是否用过(1用过,0没用)
used[a[i]]=1;
a[i]=x-1;
}

二、优化

“我们看到,刚才的方法有两重循环,时间复杂度为 O(N^2) ,找左侧用过的数的数量很费时间。

只要把used函数用线段树或树状数组维护区间和,就可以只花log的时间就求出左侧小于自己的数的个数了。” (摘自日报)

三、代码

#include<cstdio>
using namespace std;
#define N 1000001
int n,tr[N];
long long ans,fac[N];
inline void add(int x,int k) {
for (; x<=n; x+=x&-x) tr[x]+=k;
}
inline int query(int x) {
int t=0;
for (; x; x-=x&-x) t+=tr[x];
return t;
}
int main() {
scanf("%d",&n);
fac[0]=1;
for (int i=1; i<=n; i++) {
fac[i]=fac[i-1]*i%998244353;
add(i,1);
}
for (int i=1,x; i<=n; i++) {
scanf("%d",&x);
ans=(ans+(query(x)-1)*fac[n-i])%998244353;
add(x,-1);
}
printf("%lld",ans+1);
return 0;
}

四、拓展:逆康托展开

例 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕

(1)找出第96个数

首先用96-1得到95

用95去除4! 得到3余23

有3个数比它小的数是4

所以第一位是4

用23去除3! 得到3余5

有3个数比它小的数是4但4已经在之前出现过了所以第二位是5(4在之前出现过,所以实际比5小的数是3个)

用5去除2!得到2余1

有2个数比它小的数是3,第三位是3

用1去除1!得到1余0

有1个数比它小的数是2,第二位是2

最后一个数只能是1

所以这个数是45321(摘自百度)

题解 P5367 【【模板】康托展开】的更多相关文章

  1. 洛谷 P5367 【模板】康托展开(数论,树状数组)

    题目链接 https://www.luogu.org/problem/P5367 什么是康托展开 百度百科上是这样说的:   “康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. ...

  2. [洛谷P5367]【模板】康托展开

    题目大意:给定一个$n$的排列,求它在$n$的全排列中的名次 题解:康托展开,对于一个全排列,第$i$为有$n+1-i$种选择,用变进制数表示,这一位就是$n+1-i$进制.记排列中第$[1,i)$中 ...

  3. 2021.08.05 P5357 康托展开模板(康托展开)

    2021.08.05 P5357 康托展开模板(康托展开) P5367 [模板]康托展开 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.康托展开 算法学习笔记(56): ...

  4. HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  5. LG5367 「模板」康托展开 康托展开

    问题描述 LG5367 题解 康托展开公式: \[ans=1+(\sum_{i=1}^{n}{a_i})\times(n-i)!\] 用树状数组维护一下\(\sum\)里面的东西,前缀积维护后面的东西 ...

  6. 题解报告:NYOJ 题目139 我排第几个(康托展开)

    描述 现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 输入 第一行有一个整数n(0<n<=1 ...

  7. 题解报告:NYOJ 题目143 第几是谁?(逆康托展开)

    描述 现在有"abcdefghijkl”12个字符,将其按字典序排列,如果给出任意一种排列,我们能说出这个排列在所有的排列中是第几小的.但是现在我们给出它是第几小,需要你求出它所代表的序列. ...

  8. LOJ167 康托展开 题解

    题面 康托展开: 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的. X = A[0] * (n-1)! ...

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

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

随机推荐

  1. Tensorflow进阶

    第一章 图像领域,第\(i\)类图片提取到的特征: \[ feature_i=\sum_jw_{i,j}x_j+b_i \] 其中,\(j\)表示一张图片的第\(j\)个像素,\(b_i\)是偏置值( ...

  2. GO :互联网时代的 C 语言!

    摘要: 每周为您推送最有价值的开源技术内参! 技术干货 标签:独家译文 1.Go 很好,为什么我们不使用它? 在这篇文章中,我将分享一下为什么我认为它很棒,使用它的一些缺点,以及为什么它还不是我们 Z ...

  3. MSYS2 环境搭建,并整合Qt

    本机环境:Windows XP 32位MSYS2地址:http://sourceforge.net/projects/msys2/ 下载32位版本,地址:http://sourceforge.net/ ...

  4. Delphi&C#代码模拟“显示桌面”的功能(使用CreateOleObject('Shell.Application'))

    今天有人问我:“用shell打开文件(显示桌面.scf)的方式还是用模拟键盘(Win+D)显示桌面”这应该有更好的方法,就搜了搜,关键字定位“ToggleDesktop”因为显示桌面.scf的内容是: ...

  5. Dependency Injection 筆記 (4)

    续上集未完的相关设计模式... (本文摘自電子書:<.NET 依賴注入> Composite 模式 延续先前的电器比喻.现在,如果希望 UPS 不只接计算机,还要接电风扇.除湿机,可是 U ...

  6. QT中获取选中的radioButton的两种方法(动态取得控件的objectName之后,对名字进行比较)

    QT中获取选中的radioButton的两种方法   QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioBu ...

  7. 模态对话框测试 MFC中的模态对话框与非模态对话框

    http://blog.csdn.net/u010839382/article/details/52972427 http://blog.csdn.net/u010839382/article/det ...

  8. APP导航设计九法

    近期在设计APP原型,用EXCEL,用Axure.但无论工具如何,产品本身的界面布局和交互设计确实逃不掉的!网络中有关于APP导航设计的总结: 第一种:app标签导航  易用性:★★★★★   趣味性 ...

  9. orm多表操作

    一.创建表 1.一对多 必须在"多"的表中创建关联字段,在外加约束 class Book(models.Model): id=models.AotuField(primary_ke ...

  10. Node 在chrome上调试

    先确保node是否安装成功: 然后 1.创建node_module块,并在同一层级创建一个服务: 如server.js: 2.下载调试工具devtool: npm install -g devtool ...