码迷,mamicode.com
首页 > 其他好文 > 详细

线段树·二

时间:2017-09-02 11:30:09      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:排列   none   isp   return   alt   names   ons   opened   logs   

1、UVA 11525 Permutation

  题意:求1~k这k个数中第N个排列。(N从0开始记)。N=sum(Si*(k-i)!)(1≤i≤k)

  思路:根据N的值的性质,联系康拓展开,不妨发现第i位的值为剩下没用的数中从小到大第Si+1个。可以用线段树来记录区间内没有用的数的个数。

技术分享
 1 #include<iostream>
 2 using namespace std;
 3 int k;
 4 const int maxk = 50010;
 5 int numk[maxk];
 6 int tree[maxk << 2];
 7 void Build(int root, int l, int r)
 8 {
 9     if (l == r)
10     {
11         tree[root] = 1;
12         return;
13     }
14     int mid = (l + r) / 2;
15     Build(root * 2, l, mid);
16     Build(root * 2 + 1, mid + 1, r);
17     tree[root] = tree[root * 2] + tree[root * 2 + 1];
18 }
19 int pos;
20 void Query(int root, int l, int r, int x)
21 {
22     if (l == r)
23     {
24         tree[root] = 0;
25         pos = l;
26         return;
27     }
28     int mid = (l + r) / 2;
29     if (x <= tree[root*2]) Query(root * 2, l, mid, x);
30     else Query(root * 2 + 1, mid + 1, r, x - tree[root * 2]);
31     tree[root] = tree[root * 2] + tree[root * 2 + 1];
32 }
33 int main()
34 {
35     int t;
36     scanf("%d", &t);
37     while (t--)
38     {
39         scanf("%d", &k);
40         Build(1, 1, k);
41         for (int i = 1; i <= k; i++)
42         {
43             int num;
44             scanf("%d", &num);
45             if (i > 1) printf(" ");
46             pos = 0;
47             Query(1, 1, k, num + 1);
48             printf("%d", pos);
49         }
50         printf("\n");
51     }
52     return 0;
53 }
View Code

 

线段树·二

标签:排列   none   isp   return   alt   names   ons   opened   logs   

原文地址:http://www.cnblogs.com/ivan-count/p/7465904.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!