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

    模板!!!

    调了好久。

  • 相关阅读:
    D. Babaei and Birthday Cake--- Codeforces Round #343 (Div. 2)
    Vijos P1389婚礼上的小杉
    AIM Tech Round (Div. 2) C. Graph and String
    HDU 5627Clarke and MST
    bzoj 3332 旧试题
    codeforces 842C Ilya And The Tree
    codesforces 671D Roads in Yusland
    Travelling
    codeforces 606C Sorting Railway Cars
    codeforces 651C Watchmen
  • 原文地址:https://www.cnblogs.com/12fs/p/7457452.html
Copyright © 2011-2022 走看看