zoukankan      html  css  js  c++  java
  • codevs 4927 线段树练习5

                    codevs 4927  线段树练习5

    题目描述 Description

    有n个数和5种操作

    add a b c:把区间[a,b]内的所有数都增加c

    set a b c:把区间[a,b]内的所有数都设为c

    sum a b:查询区间[a,b]的区间和

    max a b:查询区间[a,b]的最大值

    min a b:查询区间[a,b]的最小值

    输入描述 Input Description

    第一行两个整数n,m,第二行n个整数表示这n个数的初始值

    接下来m行操作,同题目描述

    输出描述 Output Description

    对于所有的sum、max、min询问,一行输出一个答案

    样例输入 Sample Input

    10 6

    3 9 2 8 1 7 5 0 4 6

    add 4 9 4

    set 2 6 2

    add 3 8 2

    sum 2 10

    max 1 7

    min 3 6

    样例输出 Sample Output

    49

    11

    4

    数据范围及提示 Data Size & Hint

    10%:1<n,m<=10

    30%:1<n,m<=10000

    100%:1<n,m<=100000

    保证中间结果在long long(C/C++)、int64(pascal)范围内

    考察算法:线段树双重标记

    思路:线段树区间加法和区间赋值

    先赋值,后加法(赋值后,之前的加法失效)

    注意:有将区间内的数都赋为0的情况

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define N 100001
    #define LL long long
    using namespace std;
    int n, m, x, y;
    LL z;
    string s;
    bool sign;
    struct nond {
        int ll, rr;
        LL flag1, flag2, sum;
        LL minn, maxn;
    }tree[4*N];
    void up(int now) {
        tree[now].sum = tree[now*2].sum+tree[now*2+1].sum;
        tree[now].maxn = max(tree[now*2].maxn, tree[now*2+1].maxn);
        tree[now].minn = min(tree[now*2].minn, tree[now*2+1].minn);
    }
    void down(int now) {
        if(tree[now].flag2!=-1) {
            tree[now*2].flag1 = tree[now*2+1].flag1 = 0;
            tree[now*2].flag2 = tree[now].flag2;
            tree[now*2+1].flag2 = tree[now].flag2;
            tree[now*2].sum = (tree[now*2].rr-tree[now*2].ll+1) * tree[now].flag2;
            tree[now*2+1].sum = (tree[now*2+1].rr-tree[now*2+1].ll+1) * tree[now].flag2;
            tree[now*2].maxn = tree[now].flag2;
            tree[now*2+1].maxn = tree[now].flag2;
            tree[now*2].minn = tree[now].flag2;
            tree[now*2+1].minn = tree[now].flag2;
            tree[now].flag2 = -1;
        }
        if(tree[now].flag1) {
            tree[now*2].flag1 += tree[now].flag1;
            tree[now*2+1].flag1 += tree[now].flag1;
            tree[now*2].sum += (tree[now*2].rr-tree[now*2].ll+1) * tree[now].flag1;
            tree[now*2+1].sum += (tree[now*2+1].rr-tree[now*2+1].ll+1) * tree[now].flag1;
            tree[now*2].maxn += tree[now].flag1;
            tree[now*2+1].maxn += tree[now].flag1;
            tree[now*2].minn += tree[now].flag1;
            tree[now*2+1].minn += tree[now].flag1;
            tree[now].flag1 = 0;
        }
        return ;
    }
    void build(int now, int l, int r) {
        tree[now].ll = l; tree[now].rr = r;
        tree[now].flag1 = 0; tree[now].flag2 = -1;
        if(l == r) {
            scanf("%lld", &tree[now].sum);
            tree[now].maxn = tree[now].sum;
            tree[now].minn = tree[now].sum;
            return ;
        }
        int mid = (l+r) / 2;
        build(now*2, l, mid);
        build(now*2+1, mid+1, r);
        up(now);
    }
    void add(int now, int l, int r) {
        if(tree[now].ll==l && tree[now].rr==r) {
            tree[now].flag1 += z;
            tree[now].sum += (tree[now].rr-tree[now].ll+1) * z;
            tree[now].maxn += z;
            tree[now].minn += z;
            return ;
        }
        if(tree[now].flag2!=-1 || tree[now].flag1) down(now);
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(l<=mid && mid<r) add(now*2, l, mid), add(now*2+1, mid+1, r);
        else if(r<=mid) add(now*2, l, r);
                else add(now*2+1, l, r);
        up(now);
    }
    void set(int now, int l, int r) {
        if(tree[now].ll==l && tree[now].rr==r) {
            tree[now].flag2 = z; tree[now].flag1 = 0;
            tree[now].sum = (tree[now].rr-tree[now].ll+1) * z;
            tree[now].maxn = tree[now].minn = z;
            return ;
        }
        if(tree[now].flag2!=-1 || tree[now].flag1) down(now);
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(l<=mid && mid<r) set(now*2, l, mid), set(now*2+1, mid+1, r);
        else if(r<=mid) set(now*2, l, r);
                else set(now*2+1, l, r);
        up(now);
    }
    LL query(int now, int l, int r) {
        if(tree[now].ll==l && tree[now].rr==r) return tree[now].sum;
        if(tree[now].flag2!=-1 || tree[now].flag1) down(now);
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(l<=mid && mid<r) return query(now*2, l, mid) + query(now*2+1, mid+1, r);
        else if(r<=mid) return query(now*2, l, r);
                else return query(now*2+1, l, r);
    }
    LL little(int now, int l, int r) {
        if(tree[now].ll==l && tree[now].rr==r) return tree[now].minn;
        if(tree[now].flag2!=-1 || tree[now].flag1) down(now);
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(l<=mid && mid<r) return min(little(now*2, l, mid), little(now*2+1, mid+1, r));
        else if(r<=mid) return little(now*2, l, r);
                else return little(now*2+1, l, r);
    }
    LL large(int now, int l, int r) {
        if(tree[now].ll==l && tree[now].rr==r) return tree[now].maxn;
        if(tree[now].flag2!=-1 || tree[now].flag1) down(now);
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(l<=mid && mid<r) return max(large(now*2, l, mid), large(now*2+1, mid+1, r));
        else if(r<=mid) return large(now*2, l, r);
                else return large(now*2+1, l, r);
    }
    int main() {
        scanf("%d%d", &n, &m);
        build(1, 1, n);
        for(int i = 1; i <= m; i++) {
            cin >> s;
            if(s[1] == 'd') { scanf("%d%d%lld", &x, &y, &z); add(1, x, y); continue; }
            if(s[1] == 'e') { scanf("%d%d%lld", &x, &y, &z); set(1, x, y); continue; }
            if(s[1] == 'u') { scanf("%d%d", &x, &y); printf("%lld
    ", query(1, x, y)); continue; }
            if(s[1] == 'i') { scanf("%d%d", &x, &y); printf("%lld
    ", little(1, x, y)); continue; }
            if(s[1] == 'a') { scanf("%d%d", &x, &y); printf("%lld
    ", large(1, x, y)); continue; }
        }
        return 0;
    }
  • 相关阅读:
    HTTP 状态码
    Buffer 流文件
    事件(Event)机制 .on() .emit() .once() .removeListener()
    UDP node客户端和服务端
    node全局变量  node定时器 系统自带的模块 http服务器
    标题省略,不会自动换行
    SpringBoot 出现 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
    循环对象
    npm
    根据对象的key值,查找对应的属性value
  • 原文地址:https://www.cnblogs.com/v-vip/p/8537425.html
Copyright © 2011-2022 走看看