【jzoj4933】【线段树】

本文分享了一道利用线段树解决的编程题目,详细介绍了题目的解题思路及实现代码。通过具体实例展示了线段树的应用场景和技术细节,对于理解线段树的工作原理和掌握其使用方法具有很好的参考价值。

题目大意

这里写图片描述

解题思路

没什么好说的,直接线段树,由于我打得丑,1.5sTLE。

TLE-code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a>b)?a:b)
#define fo(i,j,k) for(LL i=j;i<=k;i++)
#define fd(i,j,k) for(LL i=j;i>=k;i--)
using namespace std;
LL const maxn=1e5,inf=2147483647,inff=-inf/2;
LL n,q,ans[maxn*4+10][10],al[maxn*4+10],ar[maxn*4+10],tag[maxn*4+10][5],si[10];
void pushtag(LL pos,LL l,LL r,LL mid){
    LL op,val,poss=pos<<1;si[0]=mid-l+1,si[1]=r-mid;
    if(tag[pos][0])op=0,val=tag[pos][0];
    else op=1,val=tag[pos][1];
    fo(now,poss,poss+1){
        if(!op){
            ans[now][1]+=val*si[now-poss];
            fo(i,2,3)ans[now][i]+=val;
            if(tag[now][op]||(tag[now][!op]<inff))tag[now][op]+=val;
            else tag[now][!op]+=val;
            al[now]+=val;ar[now]+=val;
        }else if(val>inff){
            ans[now][1]=val*si[now-poss];
            fo(i,2,3)ans[now][i]=val;
            fo(i,4,6)ans[now][i]=si[now-poss];
            tag[now][op]=val;
            tag[now][!op]=0;
            al[now]=ar[now]=val;
        }
    }
    tag[pos][0]=0;tag[pos][1]=-inf;
}
void oper(LL now,LL l,LL r,LL l1,LL r1,LL op,LL val){
    LL mid=(l+r)>>1,noww=now<<1;
    if(l!=r)pushtag(now,l,r,mid);
    if((l==l1)&&(r==r1)){
        if(!op){
            ans[now][1]+=val*(r-l+1);
            fo(i,2,3)ans[now][i]+=val;
            if(tag[now][op]||(tag[now][!op]<inff))tag[now][op]+=val;
            else tag[now][!op]+=val;
            al[now]+=val;ar[now]+=val;
        }else{
            ans[now][1]=val*(r-l+1);
            fo(i,2,3)ans[now][i]=val;
            fo(i,4,6)ans[now][i]=(r-l+1);
            tag[now][op]=val;
            tag[now][!op]=0;
            al[now]=ar[now]=val;
        }
        return;
    }
    if(l1<=mid)oper(noww,l,mid,l1,min(r1,mid),op,val);
    if(mid<r1)oper(noww+1,mid+1,r,max(l1,mid+1),r1,op,val);
    ans[now][1]=ans[noww][1]+ans[noww+1][1];
    ans[now][2]=min(ans[noww][2],ans[noww+1][2]);
    ans[now][3]=max(ans[noww][3],ans[noww+1][3]);
    ans[now][4]=max(max(ans[noww][4],ans[noww+1][4]),(ans[noww][6]+ans[noww+1][5])*(ar[noww]==al[noww+1]));
    ans[now][5]=ans[noww][5];ans[now][6]=ans[noww+1][6];
    if(ar[noww]==al[noww+1]){
        if(ans[noww][5]==mid-l+1)ans[now][5]=ans[noww][5]+ans[noww+1][5];
        if(ans[noww+1][6]==r-mid)ans[now][6]=ans[noww][6]+ans[noww+1][6];
    }
    al[now]=al[noww];ar[now]=ar[noww+1];
}
LL qury(LL now,LL l,LL r,LL l1,LL r1,LL op){
    LL mid=(l+r)>>1,noww=now<<1;
    if(l!=r)pushtag(now,l,r,mid);
    if((l==l1)&&(r==r1))
        return ans[now][op];
    if(r1<=mid)return qury(noww,l,mid,l1,r1,op);
    else if(mid<l1)return qury(noww+1,mid+1,r,l1,r1,op);
    else{
        if(op==1)return qury(noww,l,mid,l1,mid,op)+qury(noww+1,mid+1,r,mid+1,r1,op);
        else if(op==2)return min(qury(noww,l,mid,l1,mid,op),qury(noww+1,mid+1,r,mid+1,r1,op));
        else if(op==3)return max(qury(noww,l,mid,l1,mid,op),qury(noww+1,mid+1,r,mid+1,r1,op));
        else if(op==4){
            LL tmp=max(qury(noww,l,mid,l1,mid,op),qury(noww+1,mid+1,r,mid+1,r1,op));
            return max(tmp,(min(ans[noww][6],mid-l1+1)+min(ans[noww+1][5],r1-mid))*(ar[noww]==al[noww+1]));
        }
    }
}
int main(){
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%lld%lld",&n,&q);LL t,l,r,v;
    fo(i,1,n)scanf("%lld",&v),oper(1,1,n,i,i,1,v);
    fo(i,1,q){
        scanf("%lld%lld%lld",&t,&l,&r);
        if(t<=3){
            scanf("%lld",&v);
            if(t<=2)oper(1,1,n,l,r,0,(t==1)?v:-v);
            else oper(1,1,n,l,r,1,v);
        }else{
            printf("%lld\n",qury(1,1,n,l,r,t-3));
        }
    }
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值