题意
bobo有两个数组
,现在他想要给他们执行下面的不同操作
1.+ x y 把的值改为
2.+ x y 把的值改为
3.+ x 求出,其中c[i]满足
分析
发现比较棘手的是操作三。仔细分析一下,虽然要取一个最大值,但是得到的
无外乎都是
这种形式。再化简一下,设
,那么
都是
的形式,会发现,这个式子取最大值时,只与
有关,也就是说,我们只需要维护的a数组与b数组前缀和的差的最大值
代码
#include<bits/stdc++.h>
#define inf 1e15
#define ll long long
#define ls now<<1
#define rs now<<1|1
using namespace std;
const int N=4e5+10;
int n,m;
ll a[N],b[N],sum[N];
struct ci
{
    int l,r;
    ll ma,tag;
}t[N<<2];
inline void pd(int now)
{
    if(!t[now].tag) return;
    t[ls].ma+=t[now].tag;
    t[rs].ma+=t[now].tag;
    t[ls].tag+=t[now].tag;
    t[rs].tag+=t[now].tag;
    t[now].tag=0;
}
inline void build(int now,int l,int r)
{
    t[now].tag=0;
    t[now].l=l;t[now].r=r;
    if(l==r)
    {
        t[now].ma=a[l]-sum[l];
        return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    t[now].ma=max(t[ls].ma,t[rs].ma);
}
inline void upd(int now,int x,int y,ll d)
{
    int l=t[now].l,r=t[now].r;
    if(l>=x&&r<=y)
    {
        t[now].ma+=d;t[now].tag+=d;
        return;
    }pd(now);
    int mid=(l+r)>>1;
    if(x<=mid) upd(ls,x,y,d);
    if(y>mid) upd(rs,x,y,d);
    t[now].ma=max(t[ls].ma,t[rs].ma);
}
inline ll ask(int now,int x,int y)
{
    int l=t[now].l,r=t[now].r;
    if(l>=x&&r<=y) return t[now].ma;
    pd(now);
    int mid=(l+r)>>1;ll val=-inf;
    if(x<=mid) val=ask(ls,x,y);
    if(y>mid) val=max(val,ask(rs,x,y));
    return val;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&b[i]);
            sum[i]=sum[i-1]+b[i];
        }
        build(1,0,n);
        for(int i=1;i<=m;i++)
        {
             int e;scanf("%d",&e);
            if(e==1)
            {
                ll x,y;scanf("%lld%lld",&x,&y);
                upd(1,x,x,-a[x]+y);a[x]=y;
            } 
            if(e==2)
            {
                ll x,y;scanf("%lld%lld",&x,&y);
                upd(1,x,n,b[x]-y);b[x]=y;
            }
            if(e==3)
            {
                ll x;scanf("%lld",&x);
                printf("%lld\n",ask(1,0,x)+a[x]-ask(1,x,x));
            }
        }
    }
    return 0;
}
京公网安备 11010502036488号