吉司机线段树10pts求条
查看原帖
吉司机线段树10pts求条
905636
_xguagua_Firefly_楼主2025/1/17 20:33
#include <bits/stdc++.h>
#define int long long
using namespace std;

constexpr int MAXN = 5e5 + 5,inf = 1e18;
int n,m,opt,l,r,x,a[MAXN];
struct Rukkhadevata
{
    int max,min,smx,smn,mxCnt,mnCnt,sum;
    int lazmx,lazmn,lazsm;
}tree[MAXN << 2];
inline void pushup(int rt)
{
    tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
    if(tree[rt << 1].max == tree[rt << 1 | 1].max)
    {
        tree[rt].max = tree[rt << 1].max;
        tree[rt].smx = max(tree[rt << 1].smx,tree[rt << 1 | 1].smx);
        tree[rt].mxCnt = tree[rt << 1].mxCnt + tree[rt << 1 | 1].mxCnt;
    }
    else if(tree[rt << 1].max > tree[rt << 1 | 1].max)
    {
        tree[rt].max = tree[rt << 1].max;
        tree[rt].smx = max(tree[rt << 1].smx,tree[rt << 1 | 1].max);
        tree[rt].mxCnt = tree[rt << 1].mxCnt;
    }
    else
    {
        tree[rt].max = tree[rt << 1 | 1].max;
        tree[rt].smx = max(tree[rt << 1].max,tree[rt << 1 | 1].smx);
        tree[rt].mxCnt = tree[rt << 1 | 1].mxCnt;
    }
    if(tree[rt << 1].min == tree[rt << 1 | 1].min)
    {
        tree[rt].min = tree[rt << 1].min;
        tree[rt].smn = min(tree[rt << 1].smn,tree[rt << 1 | 1].smn);
        tree[rt].mnCnt = tree[rt << 1].mnCnt + tree[rt << 1 | 1].mnCnt;
    }
    else if(tree[rt << 1].min < tree[rt << 1 | 1].min)
    {
        tree[rt].min = tree[rt << 1].min;
        tree[rt].smn = min(tree[rt << 1].smn,tree[rt << 1 | 1].min);
        tree[rt].mnCnt = tree[rt << 1].mnCnt;
    }
    else 
    {
        tree[rt].min = tree[rt << 1 | 1].min;
        tree[rt].smn = min(tree[rt << 1].min,tree[rt << 1 | 1].smn);
        tree[rt].mnCnt = tree[rt << 1 | 1].mnCnt;
    }
}
inline void build(int l,int r,int rt)
{
    tree[rt].lazmn = inf,tree[rt].lazmx = -inf;
    if(l == r)
    {
        tree[rt].sum = tree[rt].max = tree[rt].min = a[l];
        tree[rt].smx = -inf,tree[rt].smn = inf;
        tree[rt].mxCnt = tree[rt].mnCnt = 1;
        return ;
    }
    int mid = (l + r) >> 1;
    build(l,mid,rt << 1);
    build(mid + 1,r,rt << 1 | 1);
    pushup(rt);
}
inline void updateSum(int rt,int val,int l,int r)
{
    tree[rt].sum += (r - l + 1) * val;
    tree[rt].max += val,tree[rt].min += val;
    if(tree[rt].lazmn != inf)
        tree[rt].lazmn += val;
    if(tree[rt].lazmx != -inf)
        tree[rt].lazmx += val;
    if(tree[rt].smn != inf)
        tree[rt].smn += val;
    if(tree[rt].smx != -inf)
        tree[rt].smx += val;
    tree[rt].lazsm += val;
}
inline void updateMin(int rt,int val)
{
    if(tree[rt].max <= val)
        return ;
    tree[rt].sum += (val - tree[rt].max) * tree[rt].mxCnt;
    if(tree[rt].smn == tree[rt].max)
        tree[rt].smn = val;
    if(tree[rt].min == tree[rt].max)
        tree[rt].min = val;
    tree[rt].lazmx = min(tree[rt].lazmx,val),tree[rt].max = val,tree[rt].lazmn = val;
}
inline void updateMax(int rt,int val)
{
    if(tree[rt].min > val)
        return ;
    tree[rt].sum += (val - tree[rt].min) * tree[rt].mnCnt;
    if(tree[rt].smx == tree[rt].min)
        tree[rt].smx = val;
    if(tree[rt].max == tree[rt].min)
        tree[rt].max = val;
    tree[rt].lazmn = max(tree[rt].lazmn,val),tree[rt].min = val,tree[rt].lazmx = val;
}
inline void pushdown(int rt,int l,int r)
{
    int mid = (l + r) >> 1;
    if(tree[rt].lazsm)
    {
        updateSum(rt << 1,tree[rt].lazsm,l,mid);
        updateSum(rt << 1 | 1,tree[rt].lazsm,mid + 1,r);
        tree[rt].lazsm = 0;
    }
    if(tree[rt].lazmx != -inf)
    {
        updateMax(rt << 1,tree[rt].lazmx);
        updateMax(rt << 1 | 1,tree[rt].lazmx);
        tree[rt].lazmx = -inf;
    }
    if(tree[rt].lazmn != inf)
    {
        updateMin(rt << 1,tree[rt].lazmn);
        updateMin(rt << 1 | 1,tree[rt].lazmn);
        tree[rt].lazmn = inf;
    }
}
inline void modifySum(int rt,int l,int r,int L,int R,int val)
{
    if(L <= l && R >= r)
        return updateSum(rt,val,l,r);
    pushdown(rt,l,r);
    int mid = (l + r) >> 1;
    if(L <= mid)
        modifySum(rt << 1,l,mid,L,R,val);
    if(R > mid)
        modifySum(rt << 1 | 1,mid + 1,r,L,R,val);
    pushup(rt);
}
inline void modifyMin(int rt,int l,int r,int L,int R,int val)
{
    if(tree[rt].max <= val)
        return ;
    if(L <= l && r >= r && tree[rt].smx < val)
        return updateMin(rt,val);
    pushdown(rt,l,r);
    int mid = (l + r) >> 1;
    if(L <= mid)
        modifyMin(rt << 1,l,mid,L,R,val);
    if(R > mid)
        modifyMin(rt << 1 | 1,mid + 1,r,L,R,val);
    pushup(rt);
}
inline void modifyMax(int rt,int l,int r,int L,int R,int val)
{
    if(tree[rt].min >= val)
        return ;
    if(L <= l && R >= r && tree[rt].smn > val)
        return updateMax(rt,val);
    int mid = (l + r) >> 1;
    if(L <= mid)
        modifyMax(rt << 1,l,mid,L,R,val);
    if(R > mid)
        modifyMax(rt << 1 | 1,mid + 1,r,L,R,val);
    pushup(rt);
}
inline int querySum(int rt,int l,int r,int L,int R)
{
    if(L <= l && R >= r)
        return tree[rt].sum;
    pushdown(rt,l,r);
    int mid = (l + r) >> 1,res = 0;
    if(L <= mid)
        res += querySum(rt << 1,l,mid,L,R);
    if(R > mid)
        res += querySum(rt << 1 | 1,mid + 1,r,L,R);
    return res;
}
inline int queryMax(int rt,int l,int r,int L,int R)
{
    if(L <= l && R >= r)
        return tree[rt].max;
    pushdown(rt,l,r);
    int mid = (l + r) >> 1,res = -inf;
    if(L <= mid)
        res = max(res,queryMax(rt << 1,l,mid,L,R));
    if(R > mid)
        res= max(res,queryMax(rt << 1 | 1,mid + 1,r,L,R));
    return res;
}
inline int queryMin(int rt,int l,int r,int L,int R)
{
    if(L <= l && R >= r)
        return tree[rt].min;
    pushdown(rt,l,r);
    int mid = (l + r) >> 1,res = inf;
    if(L <= mid)
        res = min(res,queryMin(rt << 1,l,mid,L,R));
    if(R > mid)
        res = min(res,queryMin(rt << 1 | 1,mid + 1,r,L,R));
    return res;
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin >> n;
    for(int i = 1;i <= n;i++)
        cin >> a[i];
    build(1,n,1);
    cin >> m;
    while(m--)
    {
        cin >> opt >> l >> r;
        if(opt == 1)
        {
            cin >> x;
            modifySum(1,1,n,l,r,x);
        }
        if(opt == 2)
        {
            cin >> x;
            modifyMax(1,1,n,l,r,x);
        }
        if(opt == 3)
        {
            cin >> x;
            modifyMin(1,1,n,l,r,x);
        }
        if(opt == 4)
            cout << querySum(1,1,n,l,r) << '\n';
        if(opt == 5)
            cout << queryMax(1,1,n,l,r) << '\n';
        if(opt == 6)
            cout << queryMin(1,1,n,l,r) << '\n';
    }
}
2025/1/17 20:33
加载中...