UVA 11525 Permutation(树状数组)
2015-03-19 12:13
447 查看
题目意思是说 给你一个数k 然后有k个si 问你1--k 的第n个全排列是多少 注意是 1 2 3...k的全排列 不是si的
N=
由观察得知(k-i)!就是k-i个数字的全排列种数, 0=<Si<=k-i,所以显然可知如果当i==1时从第(k-1)!*s1到第n个全排列都是由第S1+1个数字開始的数列,由于每(k-1)!次排列过后,下一个排列的第1个数字都要增大1(每隔(k-1)!次,这k-1个数字都排列过一遍了,下一次仅仅能增大更前面一个,也就是第1个了)
比方对于数列{1,2,3,4},如果S1=2,当i==1的时候对于2*(4-1)!,从0到(4-1)!排列一定是1,x,x,x,从1*(4-1)!到2*(4-1)!排列一定是2,x,x,x,从2*(4-1)!到3*(4-1)!的排列一定是3,x,x,x所以我们就知道了S1等于2的话,第一个数字一定是3,这样我们就计算出了第一数字。。即我们确定这个数列一定是3,x,x,x
所以这样我们通过S1能够计算出第一个数字,S2计算出第二个数字直到求出结果。。简单的说就是由S1我们在这K个数字中找到第S1+1大的数字放在第一位,然后用剩下的K-1个数字去排列剩下的全排列,相同的在这剩下的K-1个数字中找到第S2+1大的数字放在最前面
然后就用树状数组求第Si+1大啦~ 这个就不细说了
code(比較丑陋,不要介意~):
N=
由观察得知(k-i)!就是k-i个数字的全排列种数, 0=<Si<=k-i,所以显然可知如果当i==1时从第(k-1)!*s1到第n个全排列都是由第S1+1个数字開始的数列,由于每(k-1)!次排列过后,下一个排列的第1个数字都要增大1(每隔(k-1)!次,这k-1个数字都排列过一遍了,下一次仅仅能增大更前面一个,也就是第1个了)
比方对于数列{1,2,3,4},如果S1=2,当i==1的时候对于2*(4-1)!,从0到(4-1)!排列一定是1,x,x,x,从1*(4-1)!到2*(4-1)!排列一定是2,x,x,x,从2*(4-1)!到3*(4-1)!的排列一定是3,x,x,x所以我们就知道了S1等于2的话,第一个数字一定是3,这样我们就计算出了第一数字。。即我们确定这个数列一定是3,x,x,x
所以这样我们通过S1能够计算出第一个数字,S2计算出第二个数字直到求出结果。。简单的说就是由S1我们在这K个数字中找到第S1+1大的数字放在第一位,然后用剩下的K-1个数字去排列剩下的全排列,相同的在这剩下的K-1个数字中找到第S2+1大的数字放在最前面
然后就用树状数组求第Si+1大啦~ 这个就不细说了
code(比較丑陋,不要介意~):
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #define ufor(a,b,c) for(int a=b;a<c;a++) #define dfor(a,b,c) for(int a=b;a>c;a--) #define LL long long #define clr(arr,val) memset(arr,val,sizeof(arr)) using namespace std; const int maxn=50005; int a[maxn]; int c[maxn]; int k; int lowbit(int x) { return x&(-x); } void add(int x,int val) { while(x<=k) { c[x]+=val; x+=lowbit(x); } } int sum(int x) { int num=0,ans=0; dfor(i,16,-1) { num+=(1<<i); if(num>=k || c[num]+ans >= x) num-=(1<<i); else ans+=c[num]; } return num+1; } int main() { ios::sync_with_stdio(false); int t; cin>>t; while(t--) { cin>>k; clr(c,0); ufor(i,1,k+1) add(i,1); int tmp; ufor(i,0,k) { cin>>tmp; tmp++; int ans=sum(tmp); cout<<ans; if(i!=k-1) cout<<" "; else cout<<"\n"; add(ans,-1); } } return 0; }
相关文章推荐
- UVA 11525 - Permutation(树状数组)
- UVa 11525 - Permutation (线段树 树状数组 康托展开式)
- UVA 11525 Permutation(树状数组)
- UVA 11525 Permutation(树状数组)
- uva 11525排列(树状数组 + 二分)
- UVA_11525 树状数组的活用 二分
- uva 11525 树状数组 求第k大数
- UVA 11423 - Cache Simulator(树状数组)
- 北京师范大学第十四届ACM决赛- B Squared Permutation 树状数组
- UVA 1428 || LA 4329 PingPang (树状数组)
- Beijing 2008 / UVa 1428 / POJ 3928 / HDU 2492 Ping pong (树状数组)
- uvalive 4329 Ping pong (树状数组)
- uva 1513 - Movie collection--树状数组--预留前n个位置
- 北京师范大学第十四届ACM决赛- B Squared Permutation 树状数组
- UVA 11525 Permutation (树状数组+YY)
- UVA 12086 - Potentiometers(树状数组)
- UVAlive 5798 Jupiter Atacks!(树状数组)
- 【uva】1428 - Ping pong(树状数组)
- UVa 1513 / UVALive 5902 Movie collection (树状数组)
- UVa 1513 Movie collection (树状数组)