首页 > 代码库 > UVA 11525 Permutation ——(线段树,脑筋急转弯)
UVA 11525 Permutation ——(线段树,脑筋急转弯)
只要注意到对于譬如:S1*(k-1)! 因为后面k-1个数字的全排列个数刚好是(k-1)!,那么第一个数字就是没有取过的数字的第(S1+1)个即可。取走这个数字以后这个数字就不能再用了,依次类推即可得到整个排列了。
那么随便用线段树维护一下即可。
代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #define t_mid (l+r>>1) 5 #define ls (o<<1) 6 #define rs (o<<1|1) 7 #define lson ls,l,t_mid 8 #define rson rs,t_mid+1,r 9 using namespace std; 10 const int N = 5e4 + 5; 11 12 int c[N<<2]; 13 void up(int o) {c[o] = c[ls] + c[rs];} 14 int query(int o,int l,int r,int sum) 15 { 16 if(l == r && sum == 1) 17 { 18 return l; 19 } 20 if(sum <= c[ls]) return query(lson,sum); 21 else return query(rson,sum - c[ls]); 22 } 23 void update(int o,int l,int r,int pos,int f) 24 { 25 if(l == r) 26 { 27 c[o] = f; 28 return ; 29 } 30 if(pos <= t_mid) update(lson,pos,f); 31 else update(rson,pos,f); 32 up(o); 33 } 34 void build(int o,int l,int r) 35 { 36 if(l == r) 37 { 38 c[o] = 1; 39 return ; 40 } 41 build(lson); 42 build(rson); 43 up(o); 44 } 45 46 int T,n; 47 48 int main() 49 { 50 scanf("%d",&T); 51 while(T--) 52 { 53 scanf("%d",&n); 54 build(1,1,n); 55 for(int i=1;i<=n;i++) 56 { 57 int x; 58 scanf("%d",&x); 59 int t = query(1,1,n,x+1); 60 printf("%d%c",t,i==n?‘\n‘:‘ ‘); 61 update(1,1,n,t,0); 62 } 63 } 64 return 0; 65 }
UVA 11525 Permutation ——(线段树,脑筋急转弯)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。