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

    有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

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=100010;
    const int inf=0x3f3f3f3f;
    struct node
    {
        ll a_la,s_la,sum,minx,maxx;
        int l,r,flag;
    }e[N*8];
    int read()
    {
        int ans=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
        return ans*f;
    }
    inline void pushup(int ro)
    {
        e[ro].sum=e[ro<<1].sum+e[ro<<1|1].sum;
        e[ro].minx=min(e[ro<<1].minx,e[ro<<1|1].minx);
        e[ro].maxx=max(e[ro<<1].maxx,e[ro<<1|1].maxx);
    }
    void build(int ro,int l,int r)
    {
        e[ro].l=l,e[ro].r=r;
        if(l==r) {int t=read();e[ro].minx=t,e[ro].maxx=t,e[ro].sum=t;}
        else 
        {
            int mid=(l+r)>>1;
            build(ro<<1,l,mid);build(ro<<1|1,mid+1,r);pushup(ro);
        }
        return;
    }
    inline void down(int ro)
    {
        if(e[ro].flag)
        {
            e[ro<<1].flag=e[ro<<1|1].flag=1;
            e[ro].flag=0;
            int mid=(e[ro].l+e[ro].r)>>1;
            e[ro<<1].sum=e[ro].s_la*(mid-e[ro].l+1);
            e[ro<<1|1].sum=e[ro].s_la*(e[ro].r-mid);
            e[ro<<1].maxx=e[ro<<1].minx=e[ro<<1|1].maxx=e[ro<<1|1].minx=e[ro].s_la;
            e[ro<<1].s_la=e[ro<<1|1].s_la=e[ro].s_la;
            e[ro<<1].a_la=e[ro<<1|1].a_la=e[ro].s_la=0;
        }
        if(e[ro].a_la)
        {
            e[ro<<1].a_la+=e[ro].a_la;
            e[ro<<1|1].a_la+=e[ro].a_la;
            e[ro<<1].sum+=e[ro].a_la*(e[ro<<1].r-e[ro<<1].l+1);
            e[ro<<1].minx+=e[ro].a_la;
            e[ro<<1].maxx+=e[ro].a_la;
            e[ro<<1|1].sum+=e[ro].a_la*(e[ro<<1|1].r-e[ro<<1|1].l+1);
            e[ro<<1|1].minx+=e[ro].a_la;
            e[ro<<1|1].maxx+=e[ro].a_la;
            e[ro].a_la=0;
        }
        
    }
    void add(int ro,int l,int r,int x)
    {    
        down(ro);
        if(l<=e[ro].l&&e[ro].r<=r)
        {
            if(e[ro].s_la) e[ro].s_la+=x;
            else e[ro].a_la+=x;
            e[ro].sum+=x*(e[ro].r-e[ro].l+1);
            e[ro].maxx+=x;
            e[ro].minx+=x;    
            return;
        }
        
        int mid=(e[ro].l+e[ro].r)>>1;
        if(l<=mid) add(ro<<1,l,r,x);
        if(r>mid)  add(ro<<1|1,l,r,x);
        pushup(ro);
        return;
    }
    void set(int ro,int l,int r,int x)
    {
        down(ro);
        if(l<=e[ro].l&&e[ro].r<=r)
        {
            e[ro].sum=x*(e[ro].r-e[ro].l+1);
            e[ro].minx=x;
            e[ro].maxx=x;
            e[ro].a_la=0;
            e[ro].s_la=x;
            e[ro].flag=1;
            return;
        }
        
        int mid=(e[ro].l+e[ro].r)>>1;
        if(l<=mid) set(ro<<1,l,r,x);
        if(r>mid)  set(ro<<1|1,l,r,x);
        pushup(ro);
        return;
    }
    ll asum(int ro,int l,int r)
    {
        down(ro);
        if(l<=e[ro].l&&e[ro].r<=r) return e[ro].sum;
        int mid=(e[ro].l+e[ro].r)>>1;
        ll ans=0;
        if(l<=mid) ans+=asum(ro<<1,l,r);
        if(mid<r) ans+=asum(ro<<1|1,l,r);
        return ans;
    }
    
    ll amin(int ro,int l,int r)
    {
        down(ro);
        if(l<=e[ro].l&&e[ro].r<=r) return e[ro].minx;
        
        int mid=(e[ro].l+e[ro].r)>>1;
        ll answer=inf;
        if(l<=mid) answer=min(answer,amin(ro<<1,l,r));
        if(mid<r)  answer=min(answer,amin(ro<<1|1,l,r));
        return answer;
    }
    ll amax(int ro,int l,int r)
    {
        down(ro);
        if(l<=e[ro].l&&e[ro].r<=r) return e[ro].maxx;    
        int mid=(e[ro].l+e[ro].r)>>1;
        ll answer=-inf;
        if(l<=mid) answer=max(answer,amax(ro<<1,l,r));
        if(mid<r)  answer=max(answer,amax(ro<<1|1,l,r));
        return answer;
    }
    int main()
    {
        int n,m;
        n=read(),m=read();
        build(1,1,n);
        //for(int i=1;i<=20;i++) printf("%lld %lld %lld %d %d
    ",e[i].sum,e[i].maxx,e[i].minx,e[i].l,e[i].r);
        for(int i=1;i<=m;i++)
        {
            char ch[10];
            scanf("%s",ch);
            if(ch[1]=='d') {int l,r,x;scanf("%d %d %d",&l,&r,&x);add(1,l,r,x);}
            //for(int i=1;i<=20;i++) printf("%lld %lld %lld %d %d
    ",e[i].sum,e[i].maxx,e[i].minx,e[i].l,e[i].r);
            if(ch[1]=='e') {int l,r,x;scanf("%d %d %d",&l,&r,&x);set(1,l,r,x);}
            if(ch[1]=='u') {int l,r;scanf("%d %d",&l,&r);printf("%lld
    ",asum(1,l,r));}
            if(ch[1]=='a') {int l,r;scanf("%d %d",&l,&r);printf("%lld
    ",amax(1,l,r));}
            if(ch[1]=='i') {int l,r;scanf("%d %d",&l,&r);printf("%lld
    ",amin(1,l,r));}
        }
        return 0;
    }
    View Code

    模板!!!

    调了好久。

  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/12fs/p/7457452.html
Copyright © 2011-2022 走看看