8.8线段树和树状数组

 题目链接   http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28619#overview

密码 acmore

还是感觉不怎么会线段树,还是得给自己另外多找点题目练练

Problem A HDU 3874

Necklace

树状数组+离线操作见http://www.cnblogs.com/gj-Acit/p/3249827.html

 

Problem B HDU 2227

Find the nondecreasing subsequences

http://www.cnblogs.com/gj-Acit/p/3258508.html

 

Problem C HDU 1541

Stars

题目意思是说给出一些星星的坐标,他们每个星星的等级是按照每个星星左下方星星的数目来定的,即所有点中满足x<x0,y<y0的点的数目就是这个店的等级。求每个等级的星星有多少个。

由于题目给出的坐标中y是按照升序给出的,所以我们只需要每输入一个坐标,就先查询它的x坐标的前方有多少个点,再将这个点插入到坐标轴中去,这样的话就可以保证每次查询的都是当前点的左下方的点的数目。这样的话就可以用树状数组来记录从1~x的区间内有多少个已经被标记的点。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define mem(a) memset(a,0,sizeof(a))
 4 #define MAX(a , b) ((a) > (b) ? (a) : (b))
 5 
 6 int TreeArray[32005], N;
 7 int ans[32005];
 8 int X[15005], Y;
 9 
10 int LowBit(int x)
11 {
12     return x&(-x);
13 }
14 
15 int GetSum(int k)//返回区间1~k有多少个点
16 {
17     int sum = 0;
18     while(k>=1)
19     {
20         sum += TreeArray[k];
21         k -= LowBit(k);
22     }
23     return sum;
24 }
25 
26 void Edit(int k,int Len)//插入一个点
27 {
28     while(k<=Len)
29     {
30         TreeArray[k] += 1;
31         k += LowBit(k);
32     }
33 }
34 
35 int main()
36 {
37     while(~scanf("%d", &N))
38     {
39         mem(ans); mem(TreeArray);
40         mem(X);
41         int Max = 0;
42         for(int i=1;i<=N;i++)
43         {
44             scanf("%d%d", &X[i], &Y);//其实不用吧每个点记录下来,可以每次都直接在区间1~32000内查找
45             X[i]+=1;//由于题目说x有可能为0,而树状数组不可以记录点0,所以全部的x都+1
46             Max = MAX(X[i], Max);//我是想要找出区间最大坐标,然后在1到最大区间内查询
47         }
48         for(int i=1;i<=N;i++)
49         {
50             ans[GetSum(X[i])]++;//先查询
51             Edit(X[i], Max);//后把点插入到坐标中去
52         }
53         for(int i=0;i<N;i++)
54         {
55             printf("%d\n", ans[i]);
56         }
57     }
58     return 0;
59 }

 

Problem D HDU 1754

I Hate It

线段树的基本操作,区间查询和节点修改

虽然此题比较简单,但是有一点学到的就是代码风格,要学会尽量让代码清晰易懂

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 4 #define mem(a) memset(a, 0, sizeof(a))
 5 #define lson k<<1, l, mid
 6 #define rson k<<1|1, mid+1, r
 7 #define MAXN 200005
 8 
 9 int Max[MAXN<<2], N, M;
10 
11 void edit(int k, int l,int r, int num, int v)
12 {
13     if(l == r)
14     {
15         Max[k] = v;
16         return ;
17     }
18     int mid = (l+r)>>1;
19     if(num <= mid)edit(lson, num, v);
20     else edit(rson, num, v);
21     Max[k] = MAX(Max[k<<1], Max[k<<1|1]);
22 }
23 
24 int query(int k,int l,int r,int L,int R)
25 {
26     if(L<=l && r<=R)return Max[k];
27     int mid = (l+r)>>1, Lans=0, Rans =0;
28     if(L <= mid) Lans = query(lson, L, R);
29     if(R > mid) Rans = query(rson, L, R);
30     return MAX(Lans, Rans);
31 }
32 
33 int main()
34 {
35     while(~scanf("%d %d", &N, &M))
36     {
37         int A, B;
38         char ch; mem(Max);
39         for(int i=1;i<=N;i++)
40         {
41             scanf("%d%*c", &A);
42             edit(1,1,N,i,A);
43         }
44         for(int i=0;i<M;i++)
45         {
46             scanf("%c %d %d%*c", &ch, &A, &B);
47             if(ch == 'Q') printf("%d\n", query(1,1,N,A,B));
48             else edit(1,1,N,A,B);
49         }
50     }
51     return 0;
52 }

 

Problem E POJ 3264

Balanced Lineup

一样都是基本操作

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define INF 1000010
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define lson k<<1, l, mid
 6 #define rson k<<1|1,mid+1, r
 7 #define MAX(a,b) (a>b?a:b)
 8 #define MIN(a,b) (a<b?a:b)
 9 #define MAXN 50005
10 
11 int minH[MAXN<<2], maxH[MAXN<<2];
12 int N, M;
13 
14 void init()
15 {
16     for(int i=0;i<=(N<<2);i++)
17     {
18         minH[i] =  INF;
19         maxH[i] = -INF;
20     }
21 }
22 
23 void edit(int k,int l,int r,int num, int val)
24 {
25     if(l==r){
26         minH[k] = maxH[k] = val;
27         return ;
28     }
29     int mid = (l+r)>>1;
30     if(num <= mid) edit(lson, num, val);
31     else edit(rson,num,val);
32     minH[k] = MIN(minH[k<<1], minH[k<<1|1]);
33     maxH[k] = MAX(maxH[k<<1], maxH[k<<1|1]);
34 }
35 
36 int query(int k,int l,int r,int L,int R,int IsMin)
37 {
38     if(L<=l && r<=R) return IsMin ? minH[k] : maxH[k];
39     int mid = (l+r)>>1, Lval=INF, Rval=INF;
40     if(L <= mid) Lval = query(lson,L,R,IsMin);
41     if(R > mid) Rval = query(rson,L,R,IsMin);
42     if(IsMin) return MIN(Lval, Rval);
43     return MAX((Lval==INF?-INF:Lval), (Rval==INF?-INF:Rval));
44 }
45 
46 int main()
47 {
48     while(~scanf("%d%d", &N, &M))
49     {
50         init();  int h;
51         for(int i=1;i<=N;i++)
52         {
53             scanf("%d", &h);
54             edit(1,1,N,i,h);
55         }
56         int  A, B;
57         for(int i=0;i<M;i++)
58         {
59             scanf("%d %d", &A, &B);
60             printf("%d\n", query(1,1,N,A,B,0) - query(1,1,N,A,B,1));
61         }
62     }
63     return 0;
64 }

 

Problem G POJ 2299

Ultra-QuickSort

http://www.cnblogs.com/gj-Acit/p/3250525.html

posted @ 2013-08-09 23:33  再见~雨泉  阅读(212)  评论(0编辑  收藏  举报