洛谷 P5367 【模板】康托展开(数论,树状数组)
题目链接
https://www.luogu.org/problem/P5367
什么是康托展开
百度百科上是这样说的:
“康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。”
是不是讲得很精(meng)致(bi)呢?
我看了无数篇博客,终于明白了一点点。
其实,康托展开就是求一个全排列在所有全排列中字典序排名第几。
举个例子:
比如说n=3的一个全排列:2 1 3 它的排名是3。
我们列出所有的全排列:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
显然,2 1 3在里面字典序排名第三。
暴力求法(基本思路)
首先我们用a[i]表示原数的第i位在当前未出现的元素中是排在第几个
比如说 "2 3 4 1"
a[1]=2 a[2]=2 a[3]=2 a[4]=0
拿a[2]举例子,到第二位时,未出现的数字有1,3,4,显然3排在第二位上,所以a[2]=2。
然后我们想,在前k-1位相等的情况下,a[k]具有什么意义?比当前情况字典序小的全排列数有多少呢?
显然是 a[k]*(k-1)! (注意阶乘的优先级比乘法运算高) 哪里显然了QAQ?
好像这叫做乘法原理来着(蒟蒻记不清楚了)
a[k]是第k位的比原排列小的数字数量,而第k-1~n位无论是什么数一定小于原数列,而且每一位都要用掉一个数字,所以就是a[k]*(k-1)*(k-2)*(k-3)*……*2*1。
最后把这些小于原排列的排列数量加起来,最后在+1就是原数列的排名。
放公式:ans=a1*0+a2*(2-1)!+a3*(3-1)!+……+an*(n-1)!+1。
时间复杂度为O(n^2)
优化
- 先预处理1到n的阶乘
- 用树状数组来维护有多少个未出现的比自己小的数(单点修改,区间查询)——一开始所有点都修改为1,然后每遇到一个点,就修改为0,最后查询1~s[k-1]有多少个1就行了(s为原数列)。
当然了,也可以用万能的线段树(只不过常数比较大罢了)
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
const int mod=;
const int maxn=;
int ss[maxn],a[maxn],s[maxn],n;
inline int lowbit(int x){
return x&(-x);
}
void update(int id,int x){
for(int i=id;i<=n;i+=lowbit(i)){
s[i]+=x;
}
}
int query(int id){
int res=;
for(int i=id;i>;i-=lowbit(i)){
res+=s[i];
}
return res;
}
long long ans,jc[maxn];
int main()
{
cin>>n;
jc[]=;
for(int i=;i<n;i++) jc[i]=jc[i-]*i%mod;
for(int i=;i<=n;i++) scanf("%d",&ss[i]);
for(int i=;i<=n;i++) update(ss[i],);
for(int i=;i<=n;i++){
update(ss[i],-);
a[n-i+]=query(ss[i]);
}
for(int i=;i<=n;i++) ans=(ans+(long long)a[i]*jc[i-]%mod)%mod;
cout<<ans+;
return ;
}
洛谷 P5367 【模板】康托展开(数论,树状数组)的更多相关文章
- 洛谷P5069 [Ynoi2015]纵使日薄西山(树状数组,set)
洛谷题目传送门 一血祭 向dllxl致敬! 算是YNOI中比较清新的吧,毕竟代码只有1.25k. 首先我们对着题意模拟,寻找一些思路. 每次选了一个最大的数后,它和它周围两个数都要减一.这样无论如何, ...
- BZOJ3262/洛谷P3810 陌上花开 分治 三维偏序 树状数组
原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 洛谷P3810 题意 有$n$个元素,第 ...
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
[NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...
- 洛谷 P4396 (离散化+莫队+树状数组)
### 洛谷P4396 题目链接 ### 题目大意: 有 n 个整数组成的数组,m 次询问,每次询问中有四个参数 l ,r,a,b .问你在[l,r] 的区间内的所有数中,值属于[a,b] 的数的个 ...
- D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]
题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...
- 洛谷P3246 [HNOI2016]序列(离线 差分 树状数组)
题意 题目链接 Sol 好像搞出了一个和题解不一样的做法(然而我考场上没写出来还是爆零0) 一个很显然的思路是考虑每个最小值的贡献. 预处理出每个数左边第一个比他小的数,右边第一个比他大的数. 那么\ ...
- 洛谷P4054 [JSOI2009]计数问题(二维树状数组)
题意 题目链接 Sol 很傻x的题.. c才100, n, m才300,直接开100个二维树状数组就做完了.. #include<bits/stdc++.h> using namespac ...
- 【洛谷3527】[POI2011] MET-Meteors(树状数组+整体二分)
点此看题面 大致题意: 一颗星球被分为\(M\)份,分别属于\(N\)个国家,有\(K\)场陨石雨,第\(i\)个国家希望收集\(P_i\)颗陨石,问其至少要在第几次陨石雨后才能达到目标. 关于整体二 ...
- 洛谷CF1030F Putting Boxes Together(树状数组)
题意: 现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i].每一个物品移动一步的代价为他的w[i].目前有2种操作: 1. x y 将第x的物品的重量改为y 2.l r 将编号在 [ l ...
- 洛谷P1527 矩阵乘法——二维树状数组+整体二分
题目:https://www.luogu.org/problemnew/show/P1527 整体二分,先把所有询问都存下来: 然后二分一个值,小于它的加到二维树状数组的前缀和里,判断一遍所有询问,就 ...
随机推荐
- C语言学习书籍推荐《Practical C++ Programming》下载
下载链接 :点我 C++ is a powerful, highly flexible, and adaptable programming language that allows software ...
- 《转载黑马教程》HTML&&CSS讲义0,,包含教程_仅供参考
今日内容 1. web概念概述 2. HTML web概念概述 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务 ...
- 2. 软件数据流图(DFD)
数据流图,简称DFD,是SA方法中用于表示系统逻辑模型的一种工具,它以图形的方式描绘数据在系统中流动和处理的过程,由于它只反映系统必须完成的逻辑功能,所以它是一种功能模型. 下图是一个飞机机票预订系统 ...
- QQ Music 音乐插件DFX unable to open skin configration 的解决方法
设置 C:\Program Files (x86)\Tencent\QQMusic\Plugins\Dfx\dfx_skin.txt 它的权限 允许程序读取执行
- 掌握简单的Makefile文件编程
Makefile描述整个程序的编译.链接规则 其中还包括了工程中用到的那些源文件及需要产生的目标文件 1)Makefile编程规则 目标(唯一):依赖(可多个) 命令... 伪目标 .PHONY:cl ...
- Spark学习之RDD
RDD概述 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的集合 ...
- android实现倒计时,最简单实现RecyclerView倒计时+SwipeRefreshLayout下拉刷新
先上效果图: RecyclerView + SwipeRefreshLayout 实现倒计时效果 MainActivity.java package top.wintp.counttimedemo1; ...
- C 单链表 实现约瑟夫环
list.h #ifndef _List_H #define _List_H typedef int ElementType; struct Node; typedef struct Node *Pt ...
- Java、Java SE、Java Web和Java EE的区别
刚接触Java对这些概念上的东西有点模糊,查了很多资料,想把它分享出来,要是哪里不对请大家指正(^_^) 1.Java 毫无疑问这就是门语言和C.C++.C#一样没什么好说的. 2.Java SE和J ...
- ThinkPHP 5.0 控制器-》请求-》数据库
ThinkPHP 5.0 控制器->请求->数据库 控制器总结 无需继承其他的类(若继承了Think/Controller,可直接调用view函数渲染模板),位置处于application ...