首页 > 其他分享 >线段树

线段树

时间:2022-09-07 23:33:24浏览次数:58  
标签:return int max 线段 maxn ans define

给出一个数组 每个数组的值代表一个集合 相邻的两个集合不能重合 问集合中的最大数是多少
线段树维护这个区间的相邻数的最大值 因为相邻的条件所以边界需要特判

#include<bits/stdc++.h>
using namespace std;
#define int long long

#define maxn 100005
#define mid ((l+r)/2)
int a[maxn],b[maxn];
int ma[maxn<<2];
// 
void push_up(int x){
    ma[x]=max(ma[x<<1],ma[x<<1|1]);
}
void build(int x,int l,int r){
    if(l==r){
        ma[x]=b[l];
        return;
    }
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    push_up(x);
}

void change(int x,int l,int r,int xx,int yy){

    if(l>xx||r<xx)return;

    if(l==r){
        ma[x]=yy;
        return;
    }
    change(x<<1,l,mid,xx,yy);
    change(x<<1|1,mid+1,r,xx,yy);
    push_up(x);
}

int query(int x,int l,int r,int ll,int rr){
    if(r<ll||l>rr)return 0;

    if(ll<=l&&rr>=r){
        return ma[x];
    }
    return max(query(x<<1,l,mid,ll,rr), query(x<<1|1,mid+1,r,ll,rr));
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];

    for(int i=1;i<=n;i++)b[i]=a[i]+max(a[i-1],a[i+1]);
    build(1,1,n);
    while(m--){
        int op,l,r;
        cin>>op>>l>>r;
        if(op==1){
            a[l]=r;
            if(l>1)
            b[l-1]=a[l-1]+max(a[l-2],a[l]);
            b[l]=a[l]+max(a[l-1],a[l+1]);
            b[l+1]=a[l+1]+max(a[l],a[l+2]);
            change(1,1,n,l-1,b[l-1]);
            change(1,1,n,l,b[l]);
            change(1,1,n,l+1,b[l+1]);
        }else{
            int ans=0;
            if((l+1)<=(r-1))
            ans=max(ans,query(1,1,n,l+1,r-1));//只能当区间长度>=2的时候才可
            ans=max(ans,a[l]);//处理边界
            ans=max(ans,a[r]);//处理边界
            if(r==(l+1)){
                ans=max(ans,a[l]+a[r]);//答案要求
            }
            cout<<ans<<'\n';
        }
    }

}

标签:return,int,max,线段,maxn,ans,define
From: https://www.cnblogs.com/liang302/p/16667722.html

相关文章

  • dp线段树优化
    题目:PottedFlowerDescriptionThelittlecattakesoverthemanagementofanewpark.Thereisalargecircularstatueinthecenterofthepark,surroundedby......
  • 可持久化线段树
    现想现写的,没有借鉴别人的任何东西。可持久化线段树1考虑不会变得太多,每次该值操作只会改变一个位置的值,其它位置是可以继承的。如果用数组,那就是下标继承。如果把数组分......
  • Slayers Come (区间覆盖种类数(dp+线段树)+ st表+二分,或者线段树) (2022杭电多校2)
    题目;给你一个长度为n的数组,每个位置上有一个野怪,野怪的攻击力和血量已知,你有m个技能,每个技能有三个值,一是可以击败的怪物,且怪物死后会攻击与它相邻的怪对于左边的怪伤害......
  • Static Query on Tree (述链剖分+线段树)(2022杭电多校)
    题意:给定一棵树,nn 个结点。根为 11,所有的结点只能走向其父亲结点。有 qq 次询问,每次询问给出 33 个结点集合 A,B,CA,B,C。问树上有多少点满足如下条件:该点可以......
  • DOS Card (线段树)(hud杭电多校)
    题目:对序列 a,回答 q 次询问:给定长度至少为 4 的区间 [L,R],在区间内选择 1对 (ai,aj)(L≤i<j≤R)可以获取分数 (ai+aj)(ai−aj) ,计算选择 2 对可以获取的最......
  • 【luogu CF633H】Fibonacci-ish II(莫队)(线段树)(矩阵乘法)
    Fibonacci-ishII题目链接:luoguCF633H题目大意给你一个序列,每次问你一个区间,把里面的数拿出来去重排序,第i个位置乘上斐波那契数列第i项之后所有数的和。思路这题......
  • 线段树
    #include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=100001;llsum[N*4];lltag[N*4];inta[N];voidpushdown(intx,intl_len,......
  • CF446C(线段树+斐波那契)
    CF446C(线段树+斐波那契数列)CF链接洛谷链接题目大意:区间加斐波那契数列,区间求和分析:一眼鉴定为线段树难点在于如何打标记,合并和传递标记对于斐波那契数列有几个性......
  • 浅淡线段树合并
    线段树,是信息学比赛中一种强有力的数据结构;动态开点,让线段树在数据范围上挣脱了束缚;线段树合并,让树上问题获得了升华。前言线段树合并的基础——动态开点线段树在初学......
  • 题解 AT5635 Shortest Path on a Line(线段树优化建图)
    题解AT5635ShortestPathonaLineDescription题目传送门题面翻译有一张有\(N\)个点,编号为\(1-N\)的无向图。做\(M\)次操作,每次操作给出三个正整数\(L,R,......