poj 3264 Balanced Lineup

一个简单的线段树,憋了我好久。问题出在了存数据的数组开得不够,因为我建立线段树时要从D-1开始,但是D那一行的元素个数,可能会超过50000所以,存数据的数组要开的大一些。

 1 #include<stdio.h>

 2 #define INF 1000000000

 3 

 4 int n, m,D,a[(50000+1000)<<1],treemin[51000<<2], treemax[51000<<2];

 5 

 6 void build()

 7 {

 8     for(int i = D-1; i > 0; i --)

 9     {

10         if(treemin[i<<1] > n || treemin[i<<1] == 0) a[treemin[i<<1]] = INF;

11         if(treemin[i<<1|1] > n || treemin[i<<1|1] == 0) a[treemin[i<<1|1]] = INF;

12         treemin[i] = (a[treemin[i<<1]]<a[treemin[i<<1|1]] ? treemin[i<<1] : treemin[i<<1|1]);

13         

14         if(treemax[i<<1] > n || treemax[i<<1] == 0) a[treemax[i<<1]] = -1;

15         if(treemax[i<<1|1] > n || treemax[i<<1|1] == 0) a[treemax[i<<1|1]] = -1;

16         treemax[i] = (a[treemax[i<<1]]>a[treemax[i<<1|1]] ? treemax[i<<1] : treemax[i<<1|1]);

17     }    

18 }

19 

20 void querymax(int cur, int x, int y, int s, int t, int& ans1)

21 {

22     int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;

23     if(x >= s && y <= t)

24     {

25         if(a[treemax[cur]] > ans1) ans1 = a[treemax[cur]];

26         return ;

27     }

28     if(mid >= s)

29         querymax(ls, x, mid, s, t, ans1);

30     if(mid + 1 <= t)

31         querymax(rs, mid + 1, y, s, t, ans1);

32 }

33 

34 void querymin(int cur, int x, int y, int s, int t, int& ans2)

35 {

36     int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;

37     if(x >= s && y <= t)

38     {

39         if(ans2 > a[treemin[cur]]) ans2 = a[treemin[cur]];

40         return;

41     }

42     if(mid >= s)

43         querymin(ls, x, mid, s, t, ans2);

44     if(mid+1<= t)

45         querymin(rs, mid+1, y, s, t, ans2);

46 }

47 

48 int solve(int x, int y)

49 {

50     int ans1 = -INF;

51     querymax(1,0,D-1,x,y,ans1);

52     int ans2 = INF;

53     querymin(1,0,D-1,x,y,ans2);

54     //printf("treemax[1]=%d\n",treemax[1]);

55     //printf("ans1 = %d  ans2 = %d\n",ans1, ans2);

56     return ans1 - ans2;

57 }

58 void init()

59 {

60     while(~scanf("%d%d",&n,&m))

61     {

62         for(int i = 1; i <= n; i ++)

63             scanf("%d",&a[i]);

64         for(D = 1; D < n + 2; D <<= 1);

65         for(int i = 0; i < D; i ++)

66         {

67             treemax[D+i] = i;

68             treemin[D+i] = i;

69         }

70         build();

71         int A, B;

72         while(m --)

73         {

74             scanf("%d%d",&A,&B);

75             printf("%d\n",solve(A,B));

76         }

77     }

78 }

79 int main()

80 {

81     init();

82     return 0;

83 }

你可能感兴趣的:(poj)