UVA11525 Permutation[康托展开 树状数组求第k小值]
| UVA - 11525 |
题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个
学了好多知识
1.康托展开
X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!
其中a[i]为第i位是i往右中的数里 第几大的-1(比他小的有几个)。
其实直接想也可以,有点类似数位DP的思想,a[n]*(n-1)!也就是a[n]个n-1的全排列,都比他小
一些例子 http://www.cnblogs.com/hxsyl/archive/2012/04/11/2443009.html
如我想知道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!是康托展开。再举个例子: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是第三个大数。
2.树状数组求区间第k小
查了一堆资料,稍微有点明白了
用a[i]表示i出现次数,用一个树状数组c[]维护a[]
设第k小为x,那么sum(x)=k
我们的做法是用二进制反向构造x
cnt是当前x的排名(<=x的个数)
把x打成二进制,从高到低枚举(1<<i),可以发现x加上(1<<i)后lowbit值是不断减小的(lowbit的定义是最右面1对应的值)
cnt加上新x的c值(这一块二进制加上的效果相当于让x在树状数组上跳了一下,结果也就是当前sum(x)的结果)
if(x>=n||cnt+c[x]>=k) 就不加了
这样就找到了最大的比x小的元素,++就行了
其实就记住,用二进制构造x-1,c数组类比着加就行了
二进制逼近,反向求和的过程
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=5e5+,INF=1e6+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,x,k;
int c[N];
inline int lowbit(int x){return x&-x;}
inline void add(int p,int v){
for(;p<=n;p+=lowbit(p)) c[p]+=v;
}
inline int sum(int p){
int res=;
for(;p>;p-=lowbit(p)) res+=c[p];
return res;
}
inline int kth(int k){
int x=,cnt=;
for(int i=;i>=;i--){
x+=(<<i);
if(x>=n||cnt+c[x]>=k) x-=(<<i);
else cnt+=c[x];
}
return x+;
}
int main(){
int T=read();
while(T--){
n=read();
memset(c,,sizeof(c));
for(int i=;i<=n;i++) add(i,);
for(int i=;i<=n;i++){
k=read()+;
x=kth(k);
printf("%d%c",x,i==n?'\n':' ');
add(x,-);
}
}
}
UVA11525 Permutation[康托展开 树状数组求第k小值]的更多相关文章
- 树状数组求第K小值 (spoj227 Ordering the Soldiers && hdu2852 KiKi's K-Number)
题目:http://www.spoj.com/problems/ORDERS/ and pid=2852">http://acm.hdu.edu.cn/showproblem.php? ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- hdu 4217 Data Structure? 树状数组求第K小
Data Structure? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- *HDU2852 树状数组(求第K小的数)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU 2852 (树状数组+无序第K小)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852 题目大意:操作①:往盒子里放一个数.操作②:从盒子里扔掉一个数.操作③:查询盒子里大于a的第K小 ...
- 树状数组求第K大(From CLJ)
; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;
随机推荐
- Redis 学习笔记(C#)
Redis安装及简单操作 Windows下安装步骤: 1. 第一步当然是先下载咯~ 地址:https://github.com/dmajkic/redis/downloads (根据自己实际情况选择 ...
- spice server dpkg-buildpackage 打包编译备忘
一般我们会通过configure,make 编译.但是为了替换版本的方便需要把他编译成deb的包,而且还需要自定义下包名.下面就记录下我的修改过程. 注:前面关于spice server的编译过程掠过 ...
- line-height行高与图片的隐匿文本间隙消除方法
(标注 文章来源 http://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-hei ...
- 使用 jQuery & CSS3 制作美丽的照片画廊
在本教程中,我们将创建一个很好看的照片画廊效果.我们的想法是,以显示专辑作为一个滑块,而当这张专辑被选中,我们将使用一个美丽的照片堆栈展示专辑的图像.在照片堆栈视图,我们可以通过将最上面的图像移动到所 ...
- 原生JS:Function对象(apply、call、bind)详解
Function对象(apply.call.bind) 原创文章,转摘请注明出处:苏福:http://www.cnblogs.com/susufufu/p/5850180.html 本文参考MDN做的 ...
- 利用Civil 3D API更改曲面的样式
如果你需要更改曲面的样式,比如更改等高线的颜色等等,在Civil 3D中,你可以通过在toolspace中选中曲面,然后点右键选择“Edit surface style…”然后切换到“Display” ...
- 源码安装ipython,并在ipython中整合spark
一.安装ipython 下载ipython, https://pypi.python.org/packages/source/i/ipython/ipython-2.2.0.tar.gz#md5=b9 ...
- 关于SharePoint 2013的工作流(二)
摸索完了如何画流程实现功能接下来,就是如何配置和部署了.在添加工作流之前,肯定需要一个审批人的配置以及阀值等等的配置. 这个的实现基本上和以前的工作流一致.写法却不一样了,模板自带的都是用js实现的. ...
- xcode8打包ipa文件, application loader上传成功,但是iTunes Connect不显示构建版本
最近更新的Xcode8.今天提交新项目时.按照以往的流程走 Xcode 编译ipa文件.applicaiton loader提交成功 但是.iTunes connect构建版本不显示.非常疑惑.平时等 ...
- iOS多线程实现2-NSThread
NSThread是轻量级的多线程开发,OC语言编写,更加面向对象,使用起来也并不复杂,但是使用NSThread需要自己管理线程生命周期.在iOS开发中很少使用它来创建一个线程,但是经常使用它做一些延时 ...