三标记线段树 码风良好 悬关求调(仅AC#2和Hack数据)
查看原帖
三标记线段树 码风良好 悬关求调(仅AC#2和Hack数据)
835856
Terry_MC楼主2025/1/22 12:42
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <deque>
#include <map>
#include <list>
using namespace std;
typedef long long ll;
const int N=5e5+10,INF=0x7fffffff;
int n,q,h[N],opp,l,r,x;
struct node{
    ll maxval,add,minh,maxh;
}tree[4*N];
int ls(int x){
    return x<<1;
}
int rs(int x){
    return x<<1|1;
}
void pushdown_add(int k,ll val){
    tree[k].maxval+=val;
    if(tree[k].minh<INF)
        tree[k].minh+=val;
    if(tree[k].maxh>-INF)
        tree[k].maxh+=val;
}
void pushdown_minh(int k,ll h){
    tree[k].maxval=min(tree[k].maxval,h);
    tree[k].minh=min(tree[k].minh,h);
    tree[k].maxh=min(tree[k].maxh,h);
}
void pushdown_maxh(int k,ll h){
    tree[k].maxval=max(tree[k].maxval,h);
    tree[k].maxh=max(tree[k].maxh,h);
    tree[k].minh=max(tree[k].minh,h);
}
void pushdown(int k){
    if(tree[k].add){
        pushdown_add(ls(k),tree[k].add);
        pushdown_add(rs(k),tree[k].add);
    }
    if(tree[k].minh!=INF){
        pushdown_maxh(ls(k),tree[k].maxh);
        pushdown_maxh(rs(k),tree[k].maxh);
    }
    if(tree[k].maxh!=-INF){
        pushdown_minh(ls(k),tree[k].minh);
        pushdown_minh(rs(k),tree[k].minh);
    }
    tree[k].add=0;
    tree[k].minh=INF;
    tree[k].maxh=-INF;
}
void build(int k,int l,int r){
    tree[k].minh=INF;
    tree[k].maxh=-INF;
    if(l==r){
        tree[k].maxval=h[l];
        return;
    }
    int mid=(l+r)>>1;
    build(ls(k),l,mid);
    build(rs(k),mid+1,r);
    tree[k].maxval=max(tree[ls(k)].maxval,tree[rs(k)].maxval);
}
void update_plus(int k,int l,int r,int x,int y,ll val){
    if(x>r||y<l) return;
    if(x<=l&&y>=r){
        pushdown_add(k,val);
        return;
    }
    pushdown(k);
    int mid=(l+r)>>1;
    update_plus(ls(k),l,mid,x,y,val);
    update_plus(rs(k),mid+1,r,x,y,val);
    tree[k].maxval=max(tree[ls(k)].maxval,tree[rs(k)].maxval);
}
void update_max(int k,int l,int r,int x,int y,ll h){
    if(x>r||y<l) return;
    if(x<=l&&y>=r){
        pushdown_maxh(k,h);
        return;
    }
    pushdown(k);
    int mid=(l+r)>>1;
    update_max(ls(k),l,mid,x,y,h);
    update_max(rs(k),mid+1,r,x,y,h);
}
void update_min(int k,int l,int r,int x,int y,ll h){
    if(x>r||y<l) return;
    if(x<=l&&y>=r){
        pushdown_minh(k,h);
        return;
    }
    pushdown(k);
    int mid=(l+r)>>1;
    update_min(ls(k),l,mid,x,y,h);
    update_min(rs(k),mid+1,r,x,y,h);
}
ll query(int k,int l,int r,int x,int y){
    if(x>r||y<l) return 0;
    if(x<=l&&y>=r) return tree[k].maxval;
    pushdown(k);
    int mid=(l+r)>>1;
    return max(query(ls(k),l,mid,x,y),query(rs(k),mid+1,r,x,y));
}
int main(){
    cin>>n>>q;
    for(int i=1;i<=n;i++)
        cin>>h[i];
    build(1,1,n);
    while(q--){
        cin>>opp>>l>>r;
        switch(opp){
        case 1:
            cin>>x;
            update_plus(1,1,n,l,r,x);
            break;
        case 2:
            cin>>x;
            update_min(1,1,n,l,r,x);
            break;
        case 3:
            cin>>x;
            update_max(1,1,n,l,r,x);
            break;
        case 4:
            cout<<query(1,1,n,l,r)<<endl;
            break;
        }
    }
    
    return 0;
}
2025/1/22 12:42
加载中...