POJ 3264 Balanced Lineup(线段树)

解题思路:

用一个数组存放线段树。根节点下标为0。假设线段树上某节点下标为i, 则:

左子节点下标为 i *2+1

右子节点下标为 i*2+2

由二叉树的定义可知叶子节点为n个时至多需要4n-1个节点

 1 #include <cstdio>
 2 #include <iostream>
 3 const int inf=0x3f3f3f3f;
 4 int maxn,minn;
 5 struct node
 6 {
 7     int l,r,mid;
 8     int maxn,minn;
 9 };
10 node t[800000];
11 void init(int root,int l,int r)
12 {
13     t[root].l=l;
14     t[root].r=r;
15     t[root].mid=(l+r)/2;
16     t[root].minn=inf;
17     t[root].maxn=-inf;
18     if(l!=r)
19     {
20         init(2*root+1,l,(l+r)/2);
21         init(2*root+2,(l+r)/2+1,r);
22     }
23 }
24 void insert(int root,int x,int num)
25 {
26     if(t[root].l==t[root].r)
27     {
28         t[root].minn=t[root].maxn=num;
29         return;
30     }
31     t[root].minn=std::min(t[root].minn,num);
32     t[root].maxn=std::max(t[root].maxn,num);
33     if(x<=t[root].mid)
34         insert(2*root+1,x,num);
35     else
36         insert(2*root+2,x,num);
37 }
38 void query(int root,int l,int r)
39 {
40     if(t[root].minn>=minn&&t[root].maxn<=maxn)
41         return;
42     if(t[root].l==l&&t[root].r==r)
43     {
44         minn=std::min(t[root].minn,minn);
45         maxn=std::max(t[root].maxn,maxn);
46         return;
47     }
48     if(r<=t[root].mid)
49         query(2*root+1,l,r);
50     else if(l>t[root].mid)
51         query(2*root+2,l,r);
52     else
53     {
54         query(2*root+1,l,t[root].mid);
55         query(2*root+2,t[root].mid+1,r);
56     }
57 }
58 int main()
59 {
60     int n,q,h;
61     scanf("%d%d",&n,&q);
62     init(0,1,n);
63     for(int i=1;i<=n;i++)
64     {
65         scanf("%d",&h);
66         insert(0,i,h);
67     }
68     int l,r;
69     for(int i=1;i<=q;i++)
70     {
71         scanf("%d%d",&l,&r);
72         maxn=-inf;
73         minn=inf;
74         query(0,l,r);
75         printf("%d\n",maxn-minn);
76     }
77     return 0;
78 }

 

posted @ 2017-04-20 15:41  Kearon  阅读(216)  评论(0编辑  收藏  举报