poj3264 划分树

题意:

给定一个序列,询问区间中最大数减去最小数的结果

和2104差不多, 代码贴过来就OK了

 1 #include <iostream>

 2 #include <algorithm>

 3 using namespace std;

 4 const int M = 100005;

 5 int toLeft[20][M], tree[20][M], sorted[M];

 6 

 7 void build(int level, int left, int right)

 8 {

 9     if (left == right) return;

10     int i, mid = (left + right) >>1;

11     int suppose = mid - left + 1;

12     for (i=left; i<=right; i++)

13         if (tree[level][i] < sorted[mid])

14             suppose--;

15     int lpos = left, rpos = mid+1;

16     for (i=left; i<=right; i++)

17     {

18         if (i == left)

19             toLeft[level][i] = 0;

20         else

21             toLeft[level][i] = toLeft[level][i-1];

22         if (tree[level][i] < sorted[mid])

23         {

24             toLeft[level][i]++;

25             tree[level+1][lpos++] = tree[level][i];

26         }

27         else if (tree[level][i] > sorted[mid])

28         {

29             tree[level+1][rpos++] = tree[level][i];

30         }

31         else 

32         {

33             if (suppose != 0)

34             {

35                 suppose--;

36                 toLeft[level][i]++;

37                 tree[level+1][lpos++] = tree[level][i];

38             }

39             else

40                 tree[level+1][rpos++] = tree[level][i];

41         }

42     }

43     build(level+1, left, mid);

44     build(level+1, mid+1, right);

45 }

46 

47 int query(int level, int left, int right, int qleft, int qright, int k)

48 {

49     if (qleft == qright)

50         return tree[level][qright];

51     int s, ss, mid = (left + right)>>1;

52     if (left == qleft)

53     {

54         s = 0;

55         ss = toLeft[level][qright];

56     }

57     else

58     {

59         s = toLeft[level][qleft-1];

60         ss = toLeft[level][qright] - s;

61     }

62     int newl, newr;

63     if (k <= ss)

64     {

65         newl = left + s;

66         newr = left + s + ss -1;

67         return query(level+1, left, mid, newl, newr, k);

68     }

69     else

70     {

71         newl = mid-left+1+qleft-s;

72         newr = mid-left+1+qright-s-ss;

73         return query(level+1, mid+1, right, newl, newr, k-ss);

74     }

75 }

76 

77 int main()

78 {

79     int n, m;

80     int i;

81     while (scanf("%d%d", &n, &m) == 2)

82     {

83         for (i=1; i<=n; i++)

84         {

85             scanf("%d", &tree[0][i]);

86             sorted[i] = tree[0][i];

87         }

88         sort(sorted+1, sorted+n+1);

89         build(0,1,n);

90         int ql, qr, k;

91         for (i=0; i<m; i++)

92         {

93             scanf("%d%d", &ql, &qr);

94             printf("%d\n", query(0, 1, n, ql, qr, qr-ql+1)-query(0, 1, n, ql, qr, 1));

95             

96         }

97     }

98     return 0;

99 }
View Code

 

你可能感兴趣的:(poj)