hdu 3308-线段树基本区间合并

来源:互联网 发布:隐藏软件工具 编辑:程序博客网 时间:2024/05/21 07:57

这题明显是线段树基本区间合并,由于第一次写也遇到了不少问题,下面将赘述。。


首先对于区间合并问题,tr里面要有rsum,lsum,msum,分别表示左连续最大,右连续最大,和区间最大,为什么这么表示,当然是为了合并操作。


先说pushup部分,不是简单的sum或者max了,按套路来,如果合并有特殊条件要加特殊条件,对于这道题要加判断arr[mi]和arr[mi+1],

由于这道题没有pushdown,所以还算简单,下一步打算做一个有pushdown的,

queue里面也有技巧,就是当mid在s和t中间时要用min确保合并的时候(当然是符合合并条件时)得到正确答案,以防多算了不在s和t中间的。

midify就是简单的midify加pushup就可以了显而易见。

由于是第一道区间合并还有理解不透彻的地方,希望继续努力,蒟蒻加油。。。

#include<stdio.h>#include<iostream>#include<cstring>using namespace std;const int MAX=1000000;struct pr {    int msum,lsum,rsum;    int left,right;                    }tr[MAX+10];int n;inline int ll(int k) {return 2*k;}          //左边的下标inline int rr(int k) {return 2*k+1;}         //右边的下标inline int mid(int kk1,int kk2) {return (kk1+kk2)>>1;}int arr[MAX];void pushup(int k){//m=r-l+1;    int l=tr[k].left,r=tr[k].right;    int mi=mid(l,r);    tr[k].lsum =tr[ll(k)].lsum;    tr[k].rsum =tr[rr(k)].rsum;//如果合并有条件则加条件    if(arr[mi]<arr[mi+1]){        if (tr[k].lsum == mi-l+1) tr[k].lsum+=tr[rr(k)].lsum;        if (tr[k].rsum == r-mi) tr[k].rsum+=tr[ll(k)].rsum;        tr[k].msum = max(tr[rr(k)].lsum+tr[ll(k)].rsum,max(tr[ll(k)].msum,tr[rr(k)].msum));        return;    }    tr[k].msum = max(tr[ll(k)].msum,tr[rr(k)].msum);}void build(int k,int s,int t) {    tr[k].left=s;tr[k].right=t;    if(s==t) {tr[k].lsum=tr[k].rsum=tr[k].msum=1;return;}                   build(ll(k),s,mid(s,t));    build(rr(k),mid(s,t)+1,t);    pushup(k);    //pushup    return;}void modify(int k,int s,int x) {    int l=tr[k].left,r=tr[k].right;    if(l==r){        arr[s]=x;        return ;    }    int mi=mid(l,r);    if(s<=mi) modify(ll(k),s,x);    else if(s>mi) modify(rr(k),s,x);    pushup(k);}int query(int k,int s,int t) {    int l=tr[k].left,r=tr[k].right;    if(l==s&&r==t) return tr[k].msum;    int mi=mid(l,r);    int res=0;    if (t<=mi) res=query(ll(k),s,t);    else if(s>mi) res=query(rr(k),s,t);    else {        res=max(query(ll(k),s,mi),query(rr(k),mi+1,t));        if(arr[mi]<arr[mi+1]){            res=max(res,min(mi-s+1,tr[ll(k)].rsum)+min(t-mi,tr[rr(k)].lsum));        }    }    return res;}int main(){    int t;    cin>>t;    int n,m;    while(t--){        memset(tr,0,sizeof(tr));        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++){            scanf("%d",&arr[i]);        }        build(1,1,n);        char c[2];        int a,b;        for(int i=0;i<m;i++){            scanf("%s%d%d",c,&a,&b);            if(c[0]=='Q'){                printf("%d\n",query(1,a+1,b+1));            }            else{                modify(1,a+1,b);            }        }    }    return 0;}


0 0