• 你能回答这些问题吗


    题目链接

    题意:

    给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

    1、“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 MAXxlry{r,i=A[i]}。

    2、“2 x y”,把 A[x] 改成 y。

    对于每个查询指令,输出一个整数表示答案。

    思路:

    用线段树维护一个区间和sum以及区间最大连续子段和dat,前缀最大连续子段和lmax,后缀最大连续子段和rmax。

    容易推出pushup为

    t[p].sum=t[p<<1].sum+t[p*2+1].sum;
    t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p*2+1].lmax);
    t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p<<1].rmax);
    t[p].dat=max(max(t[p<<1].dat,t[p*2+1].dat),t[p<<1].rmax+t[p*2+1].lmax);

    最后上代码

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #include<vector>
    #include<string>
    #include<set>
    #define ll long long
    using namespace std;
    const int N=500000<<2;
    int a[N>>2];
    struct tree
    {
        int sum,l,r,lmax,rmax,dat;
    }t[N];
    void pushup(int p)
    {
        t[p].sum=t[p<<1].sum+t[p*2+1].sum;
        t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p*2+1].lmax);
        t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p<<1].rmax);
        t[p].dat=max(max(t[p<<1].dat,t[p*2+1].dat),t[p<<1].rmax+t[p*2+1].lmax);
    }
    void build(int p,int l,int r)
    {
        t[p].l=l;
        t[p].r=r;
        if(l==r)
        {
            t[p].sum=t[p].lmax=t[p].rmax=t[p].dat=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p*2+1,mid+1,r);
        pushup(p);
    }
    void change(int p,int x,int v)
    {
        if (t[p].l==t[p].r)
        {
            t[p].dat=v;
            t[p].sum=v;
            t[p].lmax=v;
            t[p].rmax=v;
            return;
        }
        int mid=(t[p].l+t[p].r)>>1;
        if (x<=mid)
            change(p<<1,x,v);
        else
            change(p*2+1,x,v);
        pushup(p);
    }
    tree ask(int p,int l,int r)
    {
        if (l<=t[p].l && r>=t[p].r)
            return t[p];
        int mid=(t[p].l+t[p].r)>>1,val=-(1<<30);
        tree a,b,c;
        a.dat=a.sum=a.lmax=a.rmax=val;
        b.dat=b.sum=b.lmax=b.rmax=val;
        c.sum=0;
        if(l<=mid)
        {
            a=ask(p<<1,l,r);
            c.sum+=a.sum;
        }
        if(r>mid)
        {
            b=ask(p*2+1,l,r);
            c.sum+=b.sum;
        }
        c.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
        c.lmax=max(a.lmax,b.lmax+a.sum);
        if(l>mid)
            c.lmax=max(c.lmax,b.lmax);
        c.rmax=max(b.rmax,b.sum+a.rmax);
        if(r<=mid)
            c.rmax=max(c.rmax,a.rmax);
        return c;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(1,1,n);
        while(m--)
        {
            int k,x,y;
            scanf("%d%d%d",&k,&x,&y);
            
            if(k==1)
            {
                if(x>y)
                swap(x,y);
                tree r=ask(1,x,y);
                printf("%d
    ",r.dat);
            }
            if(k==2)
            {
                change(1,x,y);
            }
        }
    }
  • 相关阅读:
    Yarn的运行原理(执行流程)
    Hive 表类型简述
    hive 表类型
    Hadoop小知识点总结1
    电商交易项目案例
    乘用车辆和商用车辆销售数据分析
    搜狗搜索日志分析系统
    mysql group by 对多个字段进行分组
    group by
    输出GPLT
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/11368762.html
Copyright © 2020-2023  润新知