ACdream 1101 瑶瑶想要玩滑梯

来源:互联网 发布:用爱奇艺视频制作软件 编辑:程序博客网 时间:2024/04/29 21:29

没想到线段树的基本用法这么长时间没写了还没有忘,1A的感觉还是很爽的。

题目大意:

中文题,点此查看题目。


解题思路:

线段树的区间更新与查询。

lazy标记的使用。

当需要返回区间多个值时可以使用引用参数。



下面是代码:

#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>#include <math.h>#include <stdlib.h>using namespace std;int min(int a,int b){    if(a>b)a=b;    return a;}int max(int a,int b){    if(a<b)a=b;    return a;}int n,m,l,r,x;struct node1{    int num,l,r,lcnt,rcnt,mcnt;} node[100000<<2];char s[3];void PushUp(int l,int r,int m,int tr){    node[tr].num=-1;    node[tr].l=node[tr<<1].l;    node[tr].r=node[tr<<1|1].r;    node[tr].lcnt=node[tr<<1].lcnt;    if(node[tr<<1].lcnt==m-l+1&&node[tr<<1].r<node[tr<<1|1].l)    {        node[tr].lcnt+=node[tr<<1|1].lcnt;    }    node[tr].rcnt=node[tr<<1|1].rcnt;    if(node[tr<<1|1].rcnt==r-m&&node[tr<<1].r<node[tr<<1|1].l)    {        node[tr].rcnt+=node[tr<<1].rcnt;    }    if(node[tr<<1].r<node[tr<<1|1].l)    {        node[tr].mcnt=node[tr<<1].rcnt+node[tr<<1|1].lcnt;    }    else node[tr].mcnt=0;    node[tr].mcnt=max(node[tr<<1].mcnt,max(node[tr<<1|1].mcnt,max(node[tr].lcnt,max(node[tr].rcnt,node[tr].mcnt))));}void build(int l,int r,int tr){    if(l==r)    {        scanf("%d",&node[tr].num);        node[tr].l=node[tr].num;        node[tr].r=node[tr].num;        node[tr].lcnt=1;        node[tr].rcnt=1;        node[tr].mcnt=1;        return ;    }    int m=(l+r)>>1;    build(l,m,tr<<1);    build(m+1,r,tr<<1|1);    PushUp(l,r,m,tr);}void Pushdown(int l,int r,int tr){    if(node[tr].num!=-1)    {        node[tr<<1]=node[tr];        node[tr<<1|1]=node[tr];        node[tr].num=-1;    }}void Update(int L,int R,int num,int l,int r,int tr){    if(L<=l&&r<=R)    {        if(node[tr].num==-1)node[tr].num=0;        node[tr].num+=num;        node[tr].l=num;        node[tr].r=num;        node[tr].lcnt=1;        node[tr].rcnt=1;        node[tr].mcnt=1;        return ;    }    if(l==r)return;    Pushdown(l,r,tr);    int m=(l+r)>>1;    if(m>=L)Update(L,R,num,l,m,tr<<1);    if(m<R)Update(L,R,num,m+1,r,tr<<1|1);    PushUp(l,r,m,tr);}void copy1(int a,int b,int c,int d,int e,int &a1,int &b1,int &c1,int &d1,int &e1){    a1=a;    b1=b;    c1=c;    d1=d;    e1=e;}void query(int L,int R,int l,int r,int tr,int &lcnt,int &lnum,int &rcnt,int &rnum,int &mnum){    if(L<=l&&r<=R)    {        mnum=node[tr].mcnt;        lcnt=node[tr].lcnt;        lnum=node[tr].l;        rcnt=node[tr].rcnt;        rnum=node[tr].r;        return;    }    if(l==r)return;    int m=(l+r)>>1,a[2]={0},b[2]={0},c[2]={0},d[2]={0},e[2]={0};    Pushdown(l,r,tr);    if(m>=L)    {        query(L,R,l,m,tr<<1,a[0],b[0],c[0],d[0],e[0]);    }    if(m<R)    {        query(L,R,m+1,r,tr<<1|1,a[1],b[1],c[1],d[1],e[1]);    }    if(c[0]!=0)    {        if(a[1]!=0)        {            mnum=max(e[0],e[1]);            lcnt=a[0];            lnum=b[0];            rcnt=c[1];            rnum=d[1];            if(d[0]<b[1])            {                mnum=max(mnum,c[0]+a[1]);                if(a[0]==e[0]&&a[0]==m-l+1)                {                    lcnt+=a[1];                }                if(c[1]==e[1]&&c[1]==r-m)                {                    rcnt+=c[0];                }            }        }        else        {            copy1(a[0],b[0],c[0],d[0],e[0],lcnt,lnum,rcnt,rnum,mnum);        }    }    else    {        copy1(a[1],b[1],c[1],d[1],e[1],lcnt,lnum,rcnt,rnum,mnum);    }    PushUp(l,r,m,tr);    return ;}int main(){    scanf("%d%d",&n,&m);    build(1,n,1);    int temp[5];    for(int i=0; i<m; i++)    {        scanf("%s",s);        if(s[0]=='Q')        {            scanf("%d%d",&l,&r);            query(l,r,1,n,1,temp[0],temp[1],temp[2],temp[3],temp[4]);            printf("%d\n",max(temp[0],max(temp[2],temp[4])));        }        else if(s[0]=='U')        {            scanf("%d%d%d",&l,&r,&x);            Update(l,r,x,1,n,1);        }    }    return 0;}


0 0
原创粉丝点击