线段树·二

Posted 萌萌的美男子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树·二相关的知识,希望对你有一定的参考价值。

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

 

以上是关于线段树·二的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1436 Horizontally Visible Segments (线段树&#183;区间染色)

模板时间◆模板·II◆ 树链剖分

noip模拟9[斐波那契·数颜色·分组](洛谷模拟测试)

真·总结

bzoj2161布娃娃 权值线段树

机器学习算法·KNN