zoukankan      html  css  js  c++  java
  • HDU1754 I Hate It(树状数组 or 线段树)

    题目链接

    分析:

    本题可以用树状数组,也可以用线段树。

    树状数组:

    对于树状数组,请详见本随笔

     

    要注意的是,比如说上图,要求 2 到 4 之间的最大值, c[4] 并非 2 到 4 之间的最大值,因为 c[4] 是 1 到 4 之间的最大值。这时候就只能单独看A[4], A[3], A[2]了。

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    
    using namespace std;
    
    const int maxn = 200000 + 10;
    int num[maxn], c[maxn], n, m;
    
    int lowbit(int t){
        return t & (-t);
    }
    
    void add(int x, int d){
        num[x] = d;
        while(x <= n){
            if(c[x] < d){
                c[x] = d;
            }
            else break;
            x = x + lowbit(x);
        }
    }
    
    int get_max(int l, int r){
        int ans = num[r];
        while(l != r){
            r--;//这里也注意下
            while(r - lowbit(r) > l){   //这里注意下
                ans = max(ans, c[r]);
                r -= lowbit(r);
            }
            ans = max(ans, num[r]);
        }
        return ans;
    }
    
    int main(){
        int a, b;
        char ch[2];
        while(scanf("%d%d", &n, &m) == 2){
            memset(num, 0, sizeof(num));
            memset(c, 0, sizeof(c));
            for(int i=1; i<=n; i++){
                scanf("%d", &a);
                add(i, a);
            }
            for(int i=0; i<m; i++){
                scanf("%s%d%d", ch, &a, &b);
                if(ch[0] == 'Q'){
                    printf("%d\n", get_max(a, b));
                }
                else{
                    add(a, b);
                }
            }
        }
    
        return 0;
    }
    View Code

    线段树:

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    const int maxn = 200000+10;
    
    struct Node {
        int left;
        int right;
        int max;
    }node[maxn*4];
    
    int a[maxn];
    
    void build(int l, int r, int i) {
        node[i].left = l;
        node[i].right = r;
    
        if(l == r) {
            node[i].max = a[l];
            return ;
        }
    
        int mid = (l+r)/2;
        build(l, mid, i*2);
        build(mid+1, r, i*2+1);
        node[i].max = max(node[i*2].max, node[i*2+1].max);
    }
    
    void Update(int id, int value, int i) {
        if(node[i].left == node[i].right) {
            node[i].max = value;
            return ;
        }
    
        int mid = (node[i].left + node[i].right)/2;
        if(id <= mid) Update(id, value, i*2); //要用 <=
        else Update(id, value, 2*i+1);
    
        node[i].max = max(node[i*2].max, node[i*2+1].max);
    }
    
    int Query(int l, int r, int i) {
        if(node[i].left == l && node[i].right == r) return node[i].max;
        else {
            int mid = (node[i].left + node[i].right)/2;
            int ans = -1;
    
            if(l <= node[i].left && node[i].right <= r) return node[i].max;
            if(l <= mid) ans = max(ans, Query(l, r, i*2));
            if(mid < r) ans = max(ans, Query(l, r, i*2+1));
            return ans;
    
            //else里的这一小部分也可以这样写
            /*
            if(mid >= r) return Query(l, r, 2*i);
            else if(mid < l) return Query(l, r, 2*i+1);
            else {
                int ans = -1;
                ans = max(ans, Query(l, mid, 2*i));
                ans = max(ans, Query(mid+1, r, 2*i+1));
                return ans;
            }*/
        }
    }
    
    int main(){
        int n, m;
        while(scanf("%d%d", &n, &m) == 2) {
            for(int i=1; i<=n; i++) scanf("%d", &a[i]);
    
            build(1, n, 1);
    
            char s[2];
            int x, y;
    
            for(int i=0; i<m; i++) {
                scanf("%s %d%d", s, &x, &y);
                if(s[0] == 'Q') printf("%d\n", Query(x, y , 1));
                else Update(x, y, 1);
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    UltraEdit程序设置添加到右键菜单
    UltraEdit加入到右键菜单中
    vim常用命令
    Linux vi命令大全
    vi/vim 计算搜寻关键字数量
    vi 删除全部内容
    vi中全选的命令或者快捷方式
    VI打开和编辑多个文件的命令
    vi/vim 查找替换使用方法
    VMware workstation 与 VMware GSX Server 的区别
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3056054.html
Copyright © 2011-2022 走看看