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

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 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)范围内

     

    PS:由于数据6出错导致某些人只有90分,已于2016.5.13修正。

    出题人在此对两位90分的用户表示诚挚的歉意

    分类标签 Tags 点此展开 

     思路:区间赋值和区间加法综合操作。

    先赋值,后加法。

    注意:有一个全部赋值为0的情况。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 100001
    using namespace std;
    int n,m;
    struct nond{
        int l,r;
        long long sum,max,min;
        long long flag1,flag2;
    }tree[MAXN*4];
    void up(int now){
        tree[now].sum=tree[now*2].sum+tree[now*2+1].sum;
        tree[now].min=min(tree[now*2].min,tree[now*2+1].min);
        tree[now].max=max(tree[now*2].max,tree[now*2+1].max);
    }
    void build(int now,int l,int r){
        tree[now].l=l;tree[now].r=r;
        tree[now].flag2=-1;
        if(tree[now].l==tree[now].r){
            scanf("%lld",&tree[now].sum);
            tree[now].min=tree[now].max=tree[now].sum;
            return ;
        }
        int mid=(tree[now].l+tree[now].r)/2;
        build(now*2,l,mid);
        build(now*2+1,mid+1,r);
        up(now);
    }
    void down(int now){
        if(tree[now].flag2!=-1){
            tree[now*2].flag2=tree[now].flag2;
            tree[now*2+1].flag2=tree[now].flag2;
            tree[now*2].flag1=tree[now*2+1].flag1=0;
            tree[now*2].min=tree[now*2].max=tree[now].flag2;
            tree[now*2+1].min=tree[now*2+1].max=tree[now].flag2;
            tree[now*2].sum=(tree[now*2].r-tree[now*2].l+1)*tree[now].flag2;
            tree[now*2+1].sum=(tree[now*2+1].r-tree[now*2+1].l+1)*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].min+=tree[now].flag1;
            tree[now*2+1].min+=tree[now].flag1;
            tree[now*2].max+=tree[now].flag1;
            tree[now*2+1].max+=tree[now].flag1;
            tree[now*2].sum+=(tree[now*2].r-tree[now*2].l+1)*tree[now].flag1;
            tree[now*2+1].sum+=(tree[now*2+1].r-tree[now*2+1].l+1)*tree[now].flag1;
            tree[now].flag1=0;
        } 
    }
    void changeadd(int now,int l,int r,long long k){
        if(tree[now].l==l&&tree[now].r==r){
            tree[now].sum+=(tree[now].r-tree[now].l+1)*k;
            tree[now].min+=k;tree[now].max+=k;tree[now].flag1+=k;
            return ;
        }
        if(tree[now].flag1||tree[now].flag2!=-1)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    changeadd(now*2,l,r,k);
        else if(l>mid)    changeadd(now*2+1,l,r,k);
        else { changeadd(now*2,l,mid,k);changeadd(now*2+1,mid+1,r,k); }
        up(now);
    }
    void changeset(int now,int l,int r,long long k){
        if(tree[now].l==l&&tree[now].r==r){
            tree[now].min=k;tree[now].max=k;
            tree[now].flag1=0;tree[now].flag2=k;
            tree[now].sum=(tree[now].r-tree[now].l+1)*k;
            return ;
        }
        if(tree[now].flag1||tree[now].flag2!=-1)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    changeset(now*2,l,r,k);
        else if(l>mid)    changeset(now*2+1,l,r,k);
        else { changeset(now*2,l,mid,k);changeset(now*2+1,mid+1,r,k); }
        up(now);
    }
    long long querysum(int now,int l,int r){
        if(tree[now].l==l&&tree[now].r==r)
            return tree[now].sum;
        if(tree[now].flag1||tree[now].flag2!=-1)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    return querysum(now*2,l,r);
        else if(l>mid)    return querysum(now*2+1,l,r);
        else return querysum(now*2,l,mid)+querysum(now*2+1,mid+1,r); 
    }
    long long querymax(int now,int l,int r){
        if(tree[now].l==l&&tree[now].r==r)
            return tree[now].max;
        if(tree[now].flag1||tree[now].flag2!=-1)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    return querymax(now*2,l,r);
        else if(l>mid)    return querymax(now*2+1,l,r);
        else return max(querymax(now*2,l,mid),querymax(now*2+1,mid+1,r)); 
    }
    long long querymin(int now,int l,int r){
        if(tree[now].l==l&&tree[now].r==r)
            return tree[now].min;
        if(tree[now].flag1||tree[now].flag2!=-1)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    return querymin(now*2,l,r);
        else if(l>mid)    return querymin(now*2+1,l,r);
        else return min(querymin(now*2,l,mid),querymin(now*2+1,mid+1,r)); 
    }
    int main(){
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++){
            char opt[10];int a,b;long long c;
            cin>>opt;scanf("%d%d",&a,&b);
            if(opt[0]=='a'){
                scanf("%lld",&c);
                changeadd(1,a,b,c);
            }
            else if(opt[0]=='s'&&opt[1]=='e'){
                scanf("%lld",&c);
                changeset(1,a,b,c);
            }
            else if(opt[0]=='s'&&opt[1]=='u')
                printf("%lld
    ",querysum(1,a,b));
            else if(opt[0]=='m'&&opt[1]=='a')
                printf("%lld
    ",querymax(1,a,b));
            else printf("%lld
    ",querymin(1,a,b));
        }
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Java最常用的工具类库
    运筹学那些事,专科学生学习运筹学之网络计划技术,No.6
    这么设计实时数据平台,OLAP再也不是个事儿
    从这 5 个场景 , 看 MPC 多方安全计算的行业应用
    前后端通信进行AES加密(Vue
    圣诞快乐: 用 GaussDB T 绘制一颗圣诞树,兼论高斯数据库语法兼容
    安全多方计算新突破:阿里首次实现“公开可验证”的安全方案
    矩阵元安全多方详细介绍
    MySQL InnoDB引擎如何保证事务特性
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/8537326.html
Copyright © 2011-2022 走看看