线段树算法一些题

POJ3264

/*
算法过程:
1.构建线段树
2.在线段树中插入数据
3.对线段树进行更新(该题无更新操作)和查询
*/
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0xffffff0;
struct node{
    int l;  //区间左端点
    int r;  //区间右端点
    //下面是特殊设定的数据域
    int minx, maxx; //区间中最高和最矮的奶牛身高
}tree[800010];

int minx = INF;
int maxx = -INF;

// 对区间l,r建立线段树
void build_tree(int i, int l, int r) {
    //节点i的数据域的初始化(即根节点)
    tree[i].l = l;
    tree[i].r = r;
    tree[i].minx = INF;
    tree[i].maxx = -INF;
    if(l != r) {  
        int mid = (l + r) / 2;
        build_tree(2 * i + 1, l, mid);
        build_tree(2 * i + 2, mid + 1, r);
    }
}

void Insert(int root, int i, int h) {
    if(tree[root].l == tree[root].r) {
        tree[root].maxx = tree[root].minx = h;
        return;
    }
    tree[root].minx = min(tree[root].minx, h);
    tree[root].maxx = max(tree[root].maxx, h);
    if(i <= (tree[root].l + tree[root].r) / 2) {
        Insert(2 * root + 1, i, h);
    } else {
        Insert(2 * root + 2, i, h);
    }
}

void query(int root, int a1, int a2) {
    if(tree[root].minx >= minx && tree[root].maxx <= maxx) {
        return;
    }
    if(tree[root].l == a1 && tree[root].r == a2) {
        minx = min(minx, tree[root].minx);
        maxx = max(maxx, tree[root].maxx);
        return;
    }
    int mid = (tree[root].l + tree[root].r) / 2;
    if(a2 <= mid) {
        query(2 * root + 1, a1, a2);
    } else if(a1 > mid) {
        query(2 * root + 2, a1, a2);
    } else {
        query(2 * root + 1, a1, mid);
        query(2 * root + 2, mid + 1, a2);
    }
}
int main () {
    int N, Q;
    scanf("%d%d", &N, &Q);
    build_tree(0, 1, N);
    for(int i = 1; i <= N; ++i) {
        int h;
        scanf("%d", &h);
        Insert(0, i, h);
    }
    while(Q--) {
        int a1, a2;
        scanf("%d%d", &a1, &a2);
        minx = INF;
        maxx = -INF;
        query(0, a1, a2);
        printf("%d\n", maxx - minx);
    }
    return 0;
}

HDU - 4027

#include<bits/stdc++.h>
const int MAXN = 100010;
typedef long long ll;
typedef struct node_s {
    ll sum;
    int l, r, len;
} node_t;
node_t tree[MAXN * 4];

void update_sum(int now) {
    tree[now].sum = tree[now << 1].sum + tree[now << 1 | 1].sum;
}

void build_tree(int now, int l, int r) {
    tree[now].l = l;
    tree[now].r = r;
    tree[now].len = tree[now].r - tree[now].l + 1;
    if(tree[now].l == tree[now].r) {
        scanf("%lld", &tree[now].sum);
        return;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    build_tree(now << 1, l, mid);
    build_tree(now << 1 | 1, mid + 1, r);
    update_sum(now);
}
void update(int now, int l, int r) {
    if(tree[now].sum == tree[now].len) return;
    if(tree[now].l == tree[now].r) {
        tree[now].sum = ll(sqrt(double(tree[now].sum)));
        return;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(r <= mid) update(now << 1, l, r);
    else if(l > mid) update(now << 1 | 1, l, r);
    else {
        update(now << 1, l, mid);
        update(now << 1 | 1, mid + 1, r);
    }
    update_sum(now);
}

ll query(int now, int l, int r) {
    if(tree[now].l == l && tree[now].r == r)
        return tree[now].sum;
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(r <= mid){
        return query(now << 1, l, r);
    } else if(l > mid) {
        return query(now << 1 | 1, l, r);
    } else {
        return query(now << 1, l, mid) + query(now << 1 | 1, mid + 1, r);
    }
}
int main () {
    int size, q;
    int case_num = 0;
    while(~scanf("%d", &size)) {
        printf("Case #%d:\n", ++case_num);
        build_tree(1, 1, size);
        scanf("%d", &q);
        for(int i = 1; i <= q; ++i) {
            int T, X, Y;
            scanf("%d%d%d", &T, &X, &Y);
            if(X > Y) {
                X ^= Y, Y ^= X, X ^= Y;
            }
            if(T == 0) {
                update(1, X, Y);
            } else {
                printf("%lld\n", query(1, X, Y));
            }

        }
        printf("\n");
    }
}

HDU - 1166

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 50010;
int val;
struct node{
    int l;
    int r;
    int sum;
}tree[MAXN * 4];

void update_sum(int root) {
    tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
}
void build_tree(int root, int l, int r) {
    tree[root].l = l;
    tree[root].r = r;
    if(l == r) {
        scanf("%d", &tree[root].sum);
        return;
    }
    int mid = (l + r) >> 1;
    build_tree(root << 1, l, mid);
    build_tree(root << 1 | 1, mid + 1, r);
    update_sum(root);
}
void ADD(int now, int l, int r) {
    if(tree[now].l == tree[now].r) {
        tree[now].sum += val;
        return;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(r <= mid) {
        ADD(now << 1, l, r);
    } else if( l > mid) {
        ADD(now << 1 | 1, l, r);
    } else {
        ADD(now << 1, l, mid);
        ADD(now << 1 | 1, mid + 1, r);
    }
    update_sum(now);
}
ll QUERY(int now, int l, int r) {
    if(tree[now].l == l && tree[now].r == r) {
        return tree[now].sum;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(r <= mid) {
        return QUERY(now << 1, l, r);
    } else if(l > mid) {
        return QUERY(now << 1 | 1, l, r);
    } else {
        return QUERY(now << 1, l, mid) + QUERY(now << 1 | 1, mid + 1, r);
    }
}
int main () {
    int T;
    scanf("%d", &T);
    int case_num = 0;
    while(T--) {
        printf("Case %d:\n", ++case_num);
        int N;
        scanf("%d", &N);
        build_tree(1, 1, N);
        string op;
        int i;
        while(cin >> op) {
            if(op == "End") break;
            scanf("%d%d", &i, &val);
            if(op == "Add") {
                ADD(1, i, i);
            } else if(op == "Sub") {
                val = -val;
                ADD(1, i, i);
            } else {
                printf("%lld\n", QUERY(1, i, val));                   
            }
        }
    }
    return 0;
}

HDU 1754

#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
const int INF = 0x3f3f3f3f;
struct node{
    int l;
    int r;
    int maxx;
}tree[N * 4];
int maxx = -INF;
void update_maxx(int root) {
    tree[root].maxx = max(tree[root << 1].maxx, tree[root << 1 | 1].maxx);
}

void build_tree(int root, int l, int r) {
    tree[root].l = l;
    tree[root].r = r;
    if(l == r) {
        scanf("%d", &tree[root].maxx);
        return;
    }
    int mid = (l + r) >> 1;
    build_tree(root << 1, l, mid);
    build_tree(root << 1 | 1, mid + 1, r);
    update_maxx(root);
}

void update(int root, int l, int r) {
    if(tree[root].l == tree[root].r) {
        tree[root].maxx = maxx;
        return;
    }
    int mid = (tree[root].l + tree[root].r) >> 1;
    if(r <= mid) {
        update(root << 1, l, r);
    } else if(l > mid) {
        update(root << 1 | 1, l, r);
    } else {
        update(root << 1, l, mid);
        update(root << 1 | 1, mid + 1, r);
    }
    update_maxx(root);
} 

int query(int root, int l, int r) {
    if(tree[root].l == l && tree[root].r == r) {
        return tree[root].maxx;
    }
    int mid = (tree[root].l + tree[root].r) >> 1;
    if(r <= mid) {
        return query(root << 1, l, r);
    } else if(l > mid) {
        return query(root << 1 | 1, l, r);
    } else {
        return max(query(root << 1, l, mid), query(root << 1 | 1, mid + 1, r));
    }
}
int main () {
    int n, m;
    while(~scanf("%d%d", &n, &m)) {
        build_tree(1, 1, n);
        while(m--) {
            char op;
            int x, y;
            getchar();
            scanf("%c%d%d", &op, &x, &y);
            if(op == 'Q') {
                if(x > y) {
                    x ^= y, y ^= x, x ^= y;
                }
                printf("%d\n", query(1, x, y));
            } else {
                maxx = y;
                update(1, x, x);
            }   
        }
    }
    return 0;
}

延迟标记 HDU1698

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
struct node {
    int l, r;
    int sum, lazy;
} tree[MAXN << 2];

void update_maxx(int root) {
    tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
}

void push_down(int root) {
    if(tree[root].lazy) {
        int l = root << 1;
        int r = root << 1 | 1;
        tree[l].lazy = tree[r].lazy = tree[root].lazy;
        tree[l].sum = (tree[l].r - tree[l].l + 1) * tree[l].lazy;
        tree[r].sum = (tree[r].r - tree[r].l + 1) * tree[r].lazy; 
        tree[root].lazy = 0;
    }
}

void build_tree(int root, int l, int r) {
    tree[root].l = l;
    tree[root].r = r;
    tree[root].lazy = 0;
    if(l == r) {
        tree[root].sum = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build_tree(root << 1, l, mid);
    build_tree(root << 1 | 1, mid + 1, r);
    update_maxx(root);
}

void update(int root, int l, int r, int val) {
    if(tree[root].l == l && tree[root].r == r) {
        tree[root].lazy = val;
        tree[root].sum = (r - l + 1) * val;
        return;
    }
    push_down(root);
    int mid = (tree[root].l + tree[root].r) >> 1;
    if(r <= mid) {
        update(root << 1, l, r, val);
    } else if(l > mid) {
        update(root << 1 | 1, l, r, val);
    } else {
        update(root << 1, l, mid, val);
        update(root << 1 | 1, mid + 1, r, val);
    }
    update_maxx(root);
}

int query(int root, int l, int r) {
    if(tree[root].l == l && tree[root].r == r) {
        return tree[root].sum;
    }
    push_down(root);
    int mid = (tree[root].l + tree[root].r) >> 1;
    if(r <= mid) {
        return query(root << 1, l, r);
    } else if(l > mid) {
        return query(root << 1 | 1, l, r);
    } else{
        return query(root << 1, l, mid) + query(root << 1 | 1, mid + 1, r);
    }
}
int main () {
    int T;
    scanf("%d", &T);
    int case_num = 0;
    while(T--) {
        int n;
        scanf("%d", &n);
        build_tree(1, 1, n);
        int Q;
        scanf("%d", &Q);
        while(Q--) {
            int x, y, val;
            scanf("%d%d%d", &x, &y, &val);
            update(1, x, y, val);
        }
        printf("Case %d: The total value of the hook is %d.\n", ++case_num, query(1, 1, n));
    }
}
posted @ 2021-04-17 09:57  LightAc  阅读(85)  评论(0编辑  收藏  举报
返回顶端