• 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分的用户表示诚挚的歉意

    先下放set标记。。

    屠龙宝刀点击就送

    #include <cctype>
    #include <cstdio>
    #define N 100005
    typedef long long LL;
    inline void read(LL &x)
    {
        bool f=0;register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
        x=f?-x:x;
    }
    bool fst[N<<2|1];
    int n,m,siz[N<<2|1];
    LL ans,maxv[N<<2|1],minv[N<<2|1],fplus[N<<2|1],fset[N<<2|1],val[N<<2|1];
    inline LL max(LL a,LL b) {return a>b?a:b;}
    inline LL min(LL a,LL b) {return a>b?b:a;}
    inline void pushup(int k)
    {
        val[k]=val[k<<1]+val[k<<1|1];
        maxv[k]=max(maxv[k<<1],maxv[k<<1|1]);
        minv[k]=min(minv[k<<1],minv[k<<1|1]);
    }
    void build(int k,int l,int r)
    {
        siz[k]=r-l+1;
        if(l==r)
        {
            read(val[k]);
            maxv[k]=minv[k]=val[k];
            return;
        }
        LL mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        pushup(k);
    }
    void pushdown1(int k)
    {
        fplus[k<<1]=fplus[k<<1|1]=0;
        fset[k<<1]=fset[k<<1|1]=fset[k];
        maxv[k<<1]=minv[k<<1]=fset[k];
        maxv[k<<1|1]=minv[k<<1|1]=fset[k];
        val[k<<1]=siz[k<<1]*fset[k];
        val[k<<1|1]=siz[k<<1|1]*fset[k];
        fst[k<<1]=fst[k<<1|1]=1;
        fset[k]=0;fst[k]=0;
    }
    void pushdown2(int k)
    {
        fplus[k<<1]+=fplus[k];
        fplus[k<<1|1]+=fplus[k];
        maxv[k<<1]+=fplus[k];
        maxv[k<<1|1]+=fplus[k];
        minv[k<<1]+=fplus[k];
        minv[k<<1|1]+=fplus[k];
        val[k<<1]+=fplus[k]*siz[k<<1];
        val[k<<1|1]+=fplus[k]*siz[k<<1|1];
        fplus[k]=0;
    }
    void modify(int k,int l,int r,int x,int y,LL v)
    {
        if(l>=x&&r<=y)
        {
            val[k]+=siz[k]*v;
            maxv[k]+=v;
            minv[k]+=v;
            fplus[k]+=v;
            return;
        }
        int mid=(l+r)>>1;
        if(fst[k]) pushdown1(k);
        if(fplus[k]) pushdown2(k);
        if(x<=mid) modify(k<<1,l,mid,x,y,v);
        if(y>mid) modify(k<<1|1,mid+1,r,x,y,v);
        pushup(k);
    }
    void change(int k,int l,int r,int x,int y,LL v)
    {
        if(l>=x&&r<=y)
        {
            val[k]=siz[k]*v;
            fplus[k]=0;
            maxv[k]=minv[k]=fset[k]=v;
            fst[k]=true;
            return;
        }
        int mid=(l+r)>>1;
        if(fst[k]) pushdown1(k);
        if(fplus[k]) pushdown2(k);
        if(x<=mid) change(k<<1,l,mid,x,y,v);
        if(y>mid) change(k<<1|1,mid+1,r,x,y,v);
        pushup(k);
    }
    void sum(int k,int l,int r,int x,int y)
    {
        if(l>=x&&r<=y) {ans+=val[k];return;} 
        int mid=(l+r)>>1;
        if(fst[k]) pushdown1(k);
        if(fplus[k]) pushdown2(k);
        if(x<=mid) sum(k<<1,l,mid,x,y);
        if(y>mid) sum(k<<1|1,mid+1,r,x,y);
        pushup(k);
    }
    void Max(int k,int l,int r,int x,int y)
    {
        if(l>=x&&r<=y) {ans=max(ans,maxv[k]);return;} 
        int mid=(l+r)>>1;
        if(fst[k]) pushdown1(k);
        if(fplus[k]) pushdown2(k);
        if(x<=mid) Max(k<<1,l,mid,x,y);
        if(y>mid) Max(k<<1|1,mid+1,r,x,y);
        pushup(k);
    }
    void Min(int k,int l,int r,int x,int y)
    {
        if(l>=x&&r<=y) {ans=min(ans,minv[k]);return;}
        int mid=(l+r)>>1;
        if(fst[k]) pushdown1(k);
        if(fplus[k]) pushdown2(k);
        if(x<=mid) Min(k<<1,l,mid,x,y);
        if(y>mid) Min(k<<1|1,mid+1,r,x,y);
        pushup(k);
    }
    int main(int argc,char *argv[])
    {
        scanf("%d%d",&n,&m);
        build(1,1,n);
        char opt[10];
        LL z;
        for(int x,y;m--;)
        {
            scanf("%s%d%d",opt,&x,&y);
            if(opt[0]=='a')
            {
                read(z);
                modify(1,1,n,x,y,z);
            }
            else if(opt[0]=='s')
            {
                if(opt[1]=='e') read(z),change(1,1,n,x,y,z);
                else ans=0,sum(1,1,n,x,y),printf("%lld
    ",ans);
            }
            else if(opt[0]=='m')
            {
                if(opt[1]=='i') ans=1e18,Min(1,1,n,x,y),printf("%lld
    ",ans);
                else ans=-1e18,Max(1,1,n,x,y),printf("%lld
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    Linq to LLBL Gen Pro LLBL Gen的Linq程序设计
    应用反射技术为Infragistics Solution设计例子程序 代码简洁而且学习的效率高
    ASP.NET Web开发框架之零 项目介绍
    .NET 应用程序界面开发经验总结 设计良好的程序的表现之一就是细节做的还可以
    ORM Querier 基于TransactSQL解析的代码生成利器 帮助开发人员高效快速生成需要的ORM代码
    Visual Studio 2010 开发与调试IronPython脚本 为你的ERP/MIS 应用程序添加脚本功能
    ORM + .NET Remoting 完整例子程序 虽然现在都流行WCF,也没有必要抛弃已经掌握的.NET Remoting
    总结一下ERP .NET程序员必须掌握的.NET技术,掌握了这些技术工作起来才得心应手
    LLBL Gen 元数据编程 LLBL Gen Metadata Programming
    iPhone开发笔记[14/50]:没有开发者证书,先用模拟器也要开发
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7703545.html
Copyright © 2020-2023  润新知