zoukankan      html  css  js  c++  java
  • picks loves segment tree I

    picks loves segment tree I

    题目背景

    来源:

    ( ext {2018 WC Segment Tree Beats})

    原作者:

    ( ext {C_SUNSHINE})

    ( ext {jiry_2})

    题目描述:

    • 给定一个长度为(n)的数列(A),接下来有(m)次操作:
    • 区间([l,r])中的所有数变成(min(A_i,x))
    • 询问区间([l,r])中所有数的和
    • (n,m le 50000)
    • 我会分块!
    • (n,m le 500000)
    • 线段树?

    输入输出格式

    输入格式

    第一行两个正整数表示(N,M)

    第二行(N)个正整数,表示数列(A_i)

    接下来(M)行每行包含(3)(4)个整数,表示一个操作,具体如下:

    操作1: 1 x y x 含义:将区间([l,r])内每个数变成(min(A_i,x))

    操作2: 2 x y 含义:输出区间([l,r])内每个数的和

    输出格式

    输出包含若干行整数,即为所有操作(2)的结果。

    说明:

    对于所有的数据,有(N le 500000,M le 500000,a_i le 2 imes 10^9)

    保证所有出现的数据在(int64/long long)范围内


    本菜鸡说不清楚,直接当板子了,看网上的dalao们都写的Ⅴ,Ⅵ,Ⅶ,Ⅸ什么的,我太菜,从基础开始来吧。


    Code:

    #include <cstdio>
    #define ll long long
    #define ls id<<1
    #define rs id<<1|1
    const int N=5e5+10;
    ll mx[N<<2],se[N<<2],sum[N<<2],tag[N<<2],a[N];
    ll max(ll x,ll y){return x>y?x:y;}
    int cnt[N<<2],n,m;
    void updata(int id)
    {
        if(mx[ls]>mx[rs])
        {
            mx[id]=mx[ls];
            cnt[id]=cnt[ls];
            se[id]=max(se[ls],mx[rs]);
        }
        else if(mx[ls]<mx[rs])
        {
            mx[id]=mx[rs];
            cnt[id]=cnt[rs];
            se[id]=max(mx[ls],se[rs]);
        }
        else
        {
            mx[id]=mx[ls];
            cnt[id]=cnt[ls]+cnt[rs];
            se[id]=max(se[ls],se[rs]);
        }
        sum[id]=sum[ls]+sum[rs];
    }
    void build(int id,int l,int r)
    {
        if(l==r)
        {
            sum[id]=mx[id]=a[l];
            cnt[id]=1;
            se[id]=0;
            return;
        }
        int mid=l+r>>1;
        build(ls,l,mid),build(rs,mid+1,r);
        updata(id);
    }
    void pushdown(int id)
    {
        if(tag[id])
        {
            if(mx[ls]>tag[id])
            {
                sum[ls]-=(mx[ls]-tag[id])*cnt[ls];
                tag[ls]=mx[ls]=tag[id];
            }
            if(mx[rs]>tag[id])
            {
                sum[rs]-=(mx[rs]-tag[id])*cnt[rs];
                tag[rs]=mx[rs]=tag[id];
            }
            tag[id]=0;
        }
    }
    void change(int id,int L,int R,int l,int r,ll x)
    {
        if(mx[id]<=x) return;
        if(L==l&&R==r&&se[id]<x)
        {
            sum[id]-=(mx[id]-x)*cnt[id];
            tag[id]=mx[id]=x;
            return;
        }
        pushdown(id);
        int Mid=L+R>>1;
        if(r<=Mid) change(ls,L,Mid,l,r,x);
        else if(l>Mid) change(rs,Mid+1,R,l,r,x);
        else change(ls,L,Mid,l,Mid,x),change(rs,Mid+1,R,Mid+1,r,x);
        updata(id);
    }
    ll query(int id,int L,int R,int l,int r)
    {
        if(l==L&&r==R) return sum[id];
        pushdown(id);
        int Mid=L+R>>1;
        if(r<=Mid) return query(ls,L,Mid,l,r);
        else if(l>Mid) return query(rs,Mid+1,R,l,r);
        else return query(ls,L,Mid,l,Mid)+query(rs,Mid+1,R,Mid+1,r);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",a+i);
        build(1,1,n);
        ll x;
        for(int op,l,r,i=1;i<=m;i++)
        {
            scanf("%d%d%d",&op,&l,&r);
            if(op==1)
            {
                scanf("%lld",&x);
                change(1,1,n,l,r,x);
            }
            else
                printf("%lld
    ",query(1,1,n,l,r));
        }
        return 0;
    }
    

    2018.10.13

  • 相关阅读:
    Vue 消息无缝滚动
    请求不携带cookie问题
    vue中添加favicon
    自定义表单-校验数据规则
    vue 刷新当前页面的方式
    读阮一峰《ECMAScript 6 入门》小结
    Java进阶知识点3:更优雅地关闭资源
    Java进阶知识点2:看不懂的代码
    用Java实现异构数据库的高效通用分页查询功能
    Java进阶知识点1:白捡的扩展性
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9784133.html
Copyright © 2011-2022 走看看