牛客练习赛25 B 线段树的合并

好久没写线段树了2333

比较简单的一个线段树合并

当练手吧

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int A[N];
struct SegmentTree{
    int l,r,ans,L,R;
    #define l(x) Tree[x].l
    #define r(x) Tree[x].r
    #define ans(x) Tree[x].ans
    #define L(x) Tree[x].L
    #define R(x) Tree[x].R
}Tree[N*4];
void build(int p,int l,int r){
    l(p)=l,r(p)=r;
    if(l==r){
        ans(p)=1;
        L(p)=1;
        R(p)=1;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    ans(p)=max(ans(p*2),ans(p*2+1));
    L(p)=L(p*2);R(p)=R(p*2+1);
    if(A[mid]<A[mid+1]){
        ans(p)=max(ans(p),R(p*2)+L(p*2+1));
        if(L(p*2)==mid-l+1)L(p)+=L(p*2+1);
        if(R(p*2+1)==r-mid)R(p)+=R(p*2);
    }
}
void change(int p,int x,int val){
    if(l(p)==r(p)){
        A[x]=val;
        return;
    }
    int mid=(l(p)+r(p))/2;
    if(x<=mid) change(p*2,x,val);
    else change(p*2+1,x,val);
    ans(p)=max(ans(p*2),ans(p*2+1));
    L(p)=L(p*2);R(p)=R(p*2+1);
    if(A[mid]<A[mid+1]){
        ans(p)=max(ans(p),R(p*2)+L(p*2+1));
        if(L(p*2)==mid-l(p)+1)L(p)+=L(p*2+1);
        if(R(p*2+1)==r(p)-mid)R(p)+=R(p*2);
    }   
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int n,m,x,y;
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        cin>>A[i];
    }
    build(1,1,n);
    printf("%d\n",ans(1));
    while(m--){
        cin>>x>>y;
        change(1,x,y);
        printf("%d\n",ans(1));
    }
}

猜你喜欢

转载自blog.csdn.net/Gipsy_Danger/article/details/82216156