xtu oj 1238 线段树

来源:互联网 发布:电脑3.0端口怎么设置 编辑:程序博客网 时间:2024/06/05 14:45




做了我好长时间啊,这个线段树还是很经典的

题意:

四种操作,题目写的很清楚,就不说了,主要是这个题目对于操作2 3 用lazy标记很巧妙

题解:

线段树,lazy标记升级

void pushDown(int p){    if(lazy[p])    {        lazy[p<<1]+=lazy[p];        lazy[p<<1|1]+=lazy[p];        sum[p<<1]+=lazy[p];        sum[p<<1|1]+=lazy[p];        mins[p<<1]+=lazy[p];        mins[p<<1|1]+=lazy[p];        lazy[p]=0;    }    sum[p<<1|1]=min(sum[p<<1|1],sum[p]);    sum[p<<1|1]=max(sum[p<<1|1],mins[p]);    mins[p<<1|1]=max(mins[p<<1|1],mins[p]);    mins[p<<1|1]=min(mins[p<<1|1],sum[p]);    sum[p<<1]=min(sum[p<<1],sum[p]);    sum[p<<1]=max(sum[p<<1],mins[p]);    mins[p<<1]=max(mins[p<<1],mins[p]);    mins[p<<1]=min(mins[p<<1],sum[p]);}

后面的那8个式子子,是向下传递最大最小值

若父亲节点的最大值是max   最小值是min,那么子节点的最大最小值一定在min~max范围内

比如说:子节点的最小值要么等于min,要么大于min,若大于min的时候就要注意了,不能大于父亲节点的最大值

满足这些条件就可以得到一个完美的lazy标记的pushDown函数了


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAXN 200010#define lson l,mid,p<<1#define rson mid+1,r,p<<1|1#define mem(a) memset(a,0,sizeof(a[0]))#define LL long longLL min(LL x,LL y){return x<y?x:y;}LL max(LL x,LL y){return x>y?x:y;}LL sum[MAXN<<2];LL mins[MAXN<<2];LL lazy[MAXN<<2];void pushUp(int p){    sum[p]=max(sum[p<<1],sum[p<<1|1]);    mins[p]=min(mins[p<<1],mins[p<<1|1]);}void pushDown(int p){    if(lazy[p])    {        lazy[p<<1]+=lazy[p];        lazy[p<<1|1]+=lazy[p];        sum[p<<1]+=lazy[p];        sum[p<<1|1]+=lazy[p];        mins[p<<1]+=lazy[p];        mins[p<<1|1]+=lazy[p];        lazy[p]=0;    }    sum[p<<1|1]=min(sum[p<<1|1],sum[p]);    sum[p<<1|1]=max(sum[p<<1|1],mins[p]);    mins[p<<1|1]=max(mins[p<<1|1],mins[p]);    mins[p<<1|1]=min(mins[p<<1|1],sum[p]);    sum[p<<1]=min(sum[p<<1],sum[p]);    sum[p<<1]=max(sum[p<<1],mins[p]);    mins[p<<1]=max(mins[p<<1],mins[p]);    mins[p<<1]=min(mins[p<<1],sum[p]);}void build(int l,int r,int p){    lazy[p]=0;///重要,不知道memset和这个有什么区别    if(l==r){        scanf("%I64d",&sum[p]);        mins[p]=sum[p];        return;    }    int mid=(l+r)>>1;    build(lson);    build(rson);    pushUp(p);}LL ans_max,ans_min;void query(int l,int r,int p,LL i,LL j){    if(l>=i&&r<=j){        ans_max=max(ans_max,sum[p]);        ans_min=min(ans_min,mins[p]);        return ;    }    pushDown(p);///防止有值没有传下去    int mid=(l+r)>>1;    if(mid>=i) query(lson,i,j);    if(mid<j) query(rson,i,j);    pushUp(p);}void update_1(int l,int r,int p,LL i,LL j,LL num){    if(l>=i&&r<=j){        sum[p]+=num;        mins[p]+=num;        lazy[p]+=num;        return ;    }    pushDown(p);    int mid=(l+r)>>1;    if(mid>=i)        update_1(lson,i,j,num);    if(mid<j)        update_1(rson,i,j,num);    pushUp(p);}void update_2(int l,int r,int p,LL i,LL j,LL num){    if(l>=i&&r<=j){        sum[p]=min(sum[p],num);        mins[p]=min(mins[p],num);        return ;    }    pushDown(p);    int mid=(l+r)>>1;    if(mid>=i)        update_2(lson,i,j,num);    if(mid<j)        update_2(rson,i,j,num);    pushUp(p);}void update_3(int l,int r,int p,LL i,LL j,LL num){    if(l>=i&&r<=j){        sum[p]=max(sum[p],num);        mins[p]=max(mins[p],num);        return ;    }    pushDown(p);    int mid=(l+r)>>1;    if(mid>=i)        update_3(lson,i,j,num);    if(mid<j)        update_3(rson,i,j,num);    pushUp(p);}int main(){    int n,q,T;    //freopen("in.txt","r",stdin);    scanf("%d",&T);    while(T--)    {        mem(sum);        mem(mins);        scanf("%d%d",&n,&q);        build(1,n,1);        LL temp,a,b,c;        while(q--)        {            scanf("%I64d",&temp);            if(temp==1){                scanf("%I64d%I64d%I64d",&a,&b,&c);                update_1(1,n,1,a,b,c);            }else if(temp==2){                scanf("%I64d%I64d%I64d",&a,&b,&c);                update_2(1,n,1,a,b,c);            }else if(temp==3){                scanf("%I64d%I64d%I64d",&a,&b,&c);                update_3(1,n,1,a,b,c);            }else{                scanf("%I64d%I64d",&a,&b);                ans_max=-0x3f3f3f3f3f3f;                ans_min=0x3f3f3f3f3f3f;                query(1,n,1,a,b);                printf("%I64d %I64d\n",ans_min,ans_max);            }        }    }    return 0;}


0 0
原创粉丝点击