poj 2892 线段树 区间合并

来源:互联网 发布:linux 中断ping 编辑:程序博客网 时间:2024/05/22 23:27

题目:http://poj.org/problem?id=2892

线段树也做了不知一个了。。。。感觉自己写线段树的水平真不怎么给力。。。。。。。。。。。。。。。。。

我这个脑子哎。。。貌似,我线段树啥时候能够给力些,在给力些呢。。。。

/*题意:给出直线上一系列的村庄,如果相邻村庄都没有被破坏,则两村庄是连接的,题目给出一系列的破坏操作,对指定号码的村庄进行破坏,还有一系列的询问操作,询问与指定号码的村庄直接相连或间接相连的村庄有几个,还有一个修复操作,是对最后破坏的村庄进行修复。定义三个变量:lmax[rt] 表示从左孩子开始的连续区间个数              rmax[rt] 到右孩子截至的连续区间个数              mmax[rt] 整个区间连续的区间个数              col[rt] 表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态因为为连续区间关键步骤是pushdown 里的赋值操作和pushup的更新操作*/#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=50002;int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],col[maxn<<2],vis[maxn<<2],s[maxn],n,m;#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rchar op[2];void pushup(int rt,int l,int r){    int mid=(l+r)>>1;    lmax[rt]=lmax[rt<<1];    rmax[rt]=rmax[rt<<1|1];    mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]);    if(lmax[rt<<1]==mid-l+1)    {        lmax[rt]+=lmax[rt<<1|1];    }    if(rmax[rt<<1|1]==r-mid)    {        rmax[rt]+=rmax[rt<<1];    }    mmax[rt]=max(mmax[rt],rmax[rt<<1]+lmax[rt<<1|1]);}void pushdown(int rt,int l,int r){    int mid=(l+r)>>1;    if(col[rt]!=-1)    {        col[rt<<1]=col[rt<<1|1]=col[rt];        if(col[rt]==1)        {            lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=0;            lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=0;        }        else        {            lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=mid-l+1;            lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=r-mid;        }        col[rt]=-1;    }}void build(int rt,int l,int r){    lmax[rt]=rmax[rt]=mmax[rt]=r-l+1;    col[rt]=-1;    if(l==r)    {        return;    }    int mid=(l+r)>>1;    build(lson);    build(rson);}void updata(int rt,int l,int r,int idx,int val){    if(l==r)    {        col[rt]=val;        lmax[rt]=rmax[rt]=mmax[rt]=(val?0:r-l+1);        return;    }    pushdown(rt,l,r);    int mid=(l+r)>>1;    if(mid>=idx)updata(lson,idx,val);    else updata(rson,idx,val);    pushup(rt,l,r);}int query(int rt,int l,int r,int idx){    if(l==r||mmax[rt]==(r-l+1)||!mmax[rt])    {        return mmax[rt];    }    int mid=(l+r)>>1;    if(mid>=idx)    {           if(idx>=mid-rmax[rt<<1]+1) return lmax[rt<<1|1]+rmax[rt<<1];         return query(lson,idx);    }    else    {         if(idx<=mid+lmax[rt<<1|1]+1) return lmax[rt<<1|1]+rmax[rt<<1];          return query(rson,idx);    }}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        int i,j,idx,st=0;        build(1,1,n);        memset(vis,0,sizeof(vis));        for(i=1; i<=m; i++)        {            scanf("%s",&op);            if(op[0]=='D')            {                scanf("%d",&idx);                updata(1,1,n,idx,1);                s[st++]=idx;                vis[idx]=1;            }            else if(op[0]=='Q')            {                scanf("%d",&idx);                printf("%d\n",vis[idx]?0:query(1,1,n,idx));            }            else            {                if(st>0)                {                    updata(1,1,n,s[--st],0);                    vis[s[st]]=0;                }            }        }    }    return 0;}/*7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4*/

原创粉丝点击