• 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
    ", 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
    ", 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
    ", 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

  • 相关阅读:
    了解线程和进程
    常见的性能优化方法
    前端构建工具gulp入门教程
    在JS数组指定位置插入元素
    简单对象List自定义属性排序
    js数组排序 reverse()和sort()方法的使用
    JQuery Plugin 开发
    console.dir() 与 console.dirxml() 的使用
    随机生成10-100之间的数
    CSS3 transition过渡
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3249298.html
Copyright © 2020-2023  润新知