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. Q_DECLARE_METATYPE(继承QObject的类都已经自动注册),注册后的类型可以作为QVariant的自定义类型

    简介 这个宏用来注册一个类(含默认构造.默认析构.拷贝构造函数)为QMetaType类型 ,注册后的类型可以作为QVariant的自定义类型. 这个宏应该放在类或者结构体外面的下面,也可以放在一个非公 ...

  2. 为什么需要使用Git客户端?(使用msysgit)

    Git 是 Linux Torvalds 为了帮助管理 Linux® 内核开发而开发的一个开放源码的版本控制软件.正如所提供的文档中说的一样,“Git 是一个快速.可扩展的分布式版本控制系统,它具有极 ...

  3. 使用mingw 对libcURL,openSSL,zLib交叉编译

    使用mingw 对libcURL,openSSL,zLib交叉编译   将三个库解压到同一目录下 比如取目录名为 "source" 的目录   提前安装active-perl 配置 ...

  4. Qt之OpenSSL(有pro文件的路径格式,以及对libeay32和ssleay32的引用)

    简述 OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 简述 下载安装 使用 更多参考 下载安装 ...

  5. Laravel:php artisan key:generate三种报错解决方案,修改默认PHP版本(宝塔面板)

    为了兼容N多个网站,服务器上有3个PHP版本5.3/5.6/7.2.宝塔默认为5.3,但是laravel5.7并不支持,所以在创建线上 .env 环境配置文件,初始化应用配置时候报错了. cp .en ...

  6. Asp.Net Core 项目 EntityFramework Core 根据登录用户名过滤数据

    1.创建ASP.NET Core Web Applicatoin (MVC)项目,并且使用 Individual User Account 2.创建数据筛选接口 Models->IDataFil ...

  7. JDK JRE JVM 分别是什么

    JDK: Java Development Kit Java 开发工具包 JRE: Java Runtime Enviroment Java 运行时环境 JVM: Java Virtual Machi ...

  8. Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)

    简介 你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊.正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个 ...

  9. MySQL解决存入数据库和取出数据库时间格式问题

    我们在往数据库里存数据时,时间格式正是我们想要的,然而取数据时去出现了这种情况 这明显不是我们想要的! 解决办法: 在我们配置mysql时添加一行代码: timezone:"08:00&qu ...

  10. SpringBoot 缓存注解 与EhCache的使用

    在SpringBoot工程中配置EhCache缓存 1.在src/main/resources下新建ehcache.xml文件 eternal=true //缓存永久有效,false相反 maxEle ...