• [CodeVs4927]线段树练习5


      。。。调了三个晚上的模板题,各种千奇百怪的错误全都出现过了一遍QWQ

      题目大意:区间增减(add),区间修改为一个数(set),区间求和(sum),区间最大值(max),区间最小值(min)。

      set优先级大于add,一个节点进行set操作要将add的lazy清除,一个结点进行add操作要将set的lazy下传,对于一个结点set和add的lazy不能同时存在,查询的时候先下传set的lazy再下传add的lazy。

      好像codevs的评测姬有点奇怪,本地开四倍不会RE,评测姬会,只好开八倍了QAQ

    代码如下:

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<map>
    #define ll long long 
    using namespace std;
    const int maxn=500010,inf=1e9;
    struct poi{ll sum,max,min,delta1,delta2;int tag;}a[maxn*4];
    ll n,m,x,y,z,tot;
    char s[5];
    void read(ll &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    void pushup(int x,int l,int r)
    {
        if(l==r)return;
        a[x].sum=a[x<<1].sum+a[x<<1|1].sum;
        a[x].max=max(a[x<<1].max,a[x<<1|1].max);
        a[x].min=min(a[x<<1].min,a[x<<1|1].min);
    }
    void pushdown(int x,int l,int r)
    {
        if(l==r)return;
        int mid=(l+r)>>1;
        if(a[x].tag==1)
        {
            a[x<<1].tag=a[x<<1|1].tag=1;a[x].tag=0;
            a[x<<1].sum=(mid-l+1)*a[x].delta2;a[x<<1|1].sum=(r-mid)*a[x].delta2;
            a[x<<1].max=a[x<<1|1].max=a[x<<1].min=a[x<<1|1].min=a[x].delta2;
            a[x<<1].delta2=a[x<<1|1].delta2=a[x].delta2;
            a[x<<1].delta1=a[x<<1|1].delta1=a[x].delta2=0;
        }
        if(a[x].delta1)
        {
            a[x<<1].delta1+=a[x].delta1;a[x<<1|1].delta1+=a[x].delta1;
            a[x<<1].sum+=a[x].delta1*(mid-l+1);a[x<<1|1].sum+=a[x].delta1*(r-mid);
            a[x<<1].max+=a[x].delta1;a[x<<1].min+=a[x].delta1;
            a[x<<1|1].max+=a[x].delta1;a[x<<1|1].min+=a[x].delta1;
            a[x].delta1=0;
        }
    }
    void build(int x,int l,int r)
    {
        if(l==r){read(a[x].sum);a[x].max=a[x].min=a[x].sum;return;}
        int mid=(l+r)>>1;
        build(x<<1,l,mid);build(x<<1|1,mid+1,r);
        pushup(x,l,r);
    }
    void change(int x,int l,int r,int cl,int cr,int delta,int ty)
    {
        pushdown(x,l,r);
        if(cl<=l&&r<=cr)
        {
            if(ty)
            {
                a[x].sum+=(r-l+1)*delta;
                a[x].delta1+=delta;
                a[x].max+=delta;
                a[x].min+=delta;
            }
            else
            {
                a[x].sum=(r-l+1)*delta;
                a[x].max=a[x].min=delta;
                a[x].delta1=0;a[x].delta2=delta;
                a[x].tag=1;
            }
            return;
        }
        int mid=(l+r)>>1;
        if(cl<=mid)change(x<<1,l,mid,cl,cr,delta,ty);
        if(cr>mid)change(x<<1|1,mid+1,r,cl,cr,delta,ty);
        pushup(x,l,r);
    }
    ll query(int x,int l,int r,int cl,int cr,int ty)
    {
        pushdown(x,l,r);
        if(cl<=l&&r<=cr)
        {
            if(ty==1)return a[x].sum;
            if(ty==2)return a[x].max;
            return a[x].min;
        }
        int mid=(l+r)>>1;
        ll ret=0;
        if(ty==1)
        {
            if(cl<=mid)ret+=query(x<<1,l,mid,cl,cr,ty);
            if(cr>mid)ret+=query(x<<1|1,mid+1,r,cl,cr,ty);
        }
        if(ty==2)
        {
            ret=-inf;
            if(cl<=mid)ret=query(x<<1,l,mid,cl,cr,ty);
            if(cr>mid)ret=max(ret,query(x<<1|1,mid+1,r,cl,cr,ty));
        }
        if(ty==3)
        {
            ret=inf;
            if(cl<=mid)ret=query(x<<1,l,mid,cl,cr,ty);
            if(cr>mid)ret=min(ret,query(x<<1|1,mid+1,r,cl,cr,ty));
        }
        return ret;
    }
    int main()
    {
        read(n);read(m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);read(x);read(y);
            if(s[0]=='a')read(z),change(1,1,n,x,y,z,1);
            else if(s[0]=='s'&&s[1]=='e')read(z),change(1,1,n,x,y,z,0);
            else if(s[0]=='s'&&s[1]=='u')printf("%lld
    ",query(1,1,n,x,y,1));
            else if(s[0]=='m'&&s[1]=='a')printf("%lld
    ",query(1,1,n,x,y,2));
            else printf("%lld
    ",query(1,1,n,x,y,3));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    从aop中获取被拦截方法中的参数
    使用多线程 执行有返回值的方法
    MyBatis中#{}和${}的区别
    Java 调用api,json化结果
    Spring入门
    实用: 将程序的内容写出到excel中
    实用:Java基础流计算
    2020年7月12号笔记
    2020年7月11号笔记
    2020年7月6号笔记
  • 原文地址:https://www.cnblogs.com/Sakits/p/6411855.html
Copyright © 2020-2023  润新知