HDU 1540 && POJ 2892 Tunnel Warfare (線段樹,區間合并).

來源:互聯網
上載者:User

標籤:hdu 1540   poj 2892   tunnel warfare   線段樹   區間合并   

~~~~

第一次遇到線段樹合并的題,又被律爺教做人。TAT.

~~~~

線段樹的題意都很好理解吧。。

題目連結:

http://acm.hdu.edu.cn/showproblem.php?pid=1540

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

~~~~

My Code:200ms

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define N 55555#define lson rt<<1,s,m#define rson rt<<1|1,m+1,eusing namespace std;int st[N];struct node{    int l,r;    int lm,rm;  //維護一個區間從左右端點開始的最長區間}tre[N<<2];void build(int rt,int s,int e){    tre[rt].l=s;    tre[rt].r=e;    tre[rt].lm=tre[rt].rm=e-s+1;    if(s==e)        return ;    int m=(s+e)>>1;    build(lson);    build(rson);}void update(int p,int v,int rt,int s,int e){    if(s==e)    {        if(v) tre[rt].lm=tre[rt].rm=1; //rebuild        else tre[rt].lm=tre[rt].rm=0;  //destroy        return ;    }    int m=(s+e)>>1;    if(p<=m) update(p,v,lson);    else update(p,v,rson);    tre[rt].lm=tre[rt<<1].lm;    tre[rt].rm=tre[rt<<1|1].rm;        //若lm==區間長,還要加上右孩子的lm。    if(tre[rt<<1].lm==tre[rt<<1].r-tre[rt<<1].l+1)          tre[rt].lm=tre[rt<<1].lm+tre[rt<<1|1].lm;    if(tre[rt<<1|1].rm==tre[rt<<1|1].r-tre[rt<<1|1].l+1)   //同理~        tre[rt].rm=tre[rt<<1|1].rm+tre[rt<<1].rm;}int query(int q,int rt,int s,int e){    //總是把查詢操作歸結到一個父親節點下的兩個孩子節點的中間地區的最長連續區間。    if(s==e) return tre[rt].lm;    int m=(s+e)>>1;    int l=m-tre[rt<<1].rm;    int r=m+1+tre[rt<<1|1].lm;    if(q>l && q<r) //要尋找的端點就在該區間的連續區間中,則返回。        return tre[rt<<1].rm+tre[rt<<1|1].lm;    else if(q<=l) query(q,lson);    else query(q,rson);}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        int top=-1;        build(1,1,n);        for(int i=0;i<m;i++)        {            int x;            char str[5];            scanf("%s",str);            if(str[0]=='D')            {                scanf("%d",&x);                update(x,0,1,1,n);                st[++top]=x;            }            else if(str[0]=='R')            {                int y=st[top--];                if(top>=-1)                    update(y,1,1,1,n);            }            else if(str[0]=='Q')            {                scanf("%d",&x);                int k=query(x,1,1,n);                printf("%d\n",k);            }        }    }    return 0;}


~~~~

之前參考網上代碼所寫:300ms;


#include<cstdio>#include<cstring>#include<algorithm>#define N 55555#define lson rt<<1,s,m#define rson rt<<1|1,m+1,eusing namespace std;int st[N];struct node{    int l,r;    int lm,rm,sm; //還要維護一個區間的最長連續區間}tre[N<<2];void build(int rt,int s,int e){    tre[rt].l=s;    tre[rt].r=e;    tre[rt].lm=tre[rt].rm=tre[rt].sm=e-s+1;    if(s==e)        return ;    int m=(s+e)>>1;    build(lson);    build(rson);}void update(int p,int v,int rt,int s,int e){    if(s==e)    {        if(v) tre[rt].lm=tre[rt].rm=tre[rt].sm=1;        else tre[rt].lm=tre[rt].rm=tre[rt].sm=0;        return ;    }    int m=(s+e)>>1;    if(p<=m) update(p,v,lson);    else update(p,v,rson);    tre[rt].lm=tre[rt<<1].lm;    tre[rt].rm=tre[rt<<1|1].rm;    tre[rt].sm=max(max(tre[rt<<1].sm,tre[rt<<1|1].sm),tre[rt<<1].rm+tre[rt<<1|1].lm);    if(tre[rt<<1].lm==tre[rt<<1].r-tre[rt<<1].l+1)        tre[rt].lm=tre[rt<<1].lm+tre[rt<<1|1].lm;    if(tre[rt<<1|1].rm==tre[rt<<1|1].r-tre[rt<<1|1].l+1)        tre[rt].rm=tre[rt<<1|1].rm+tre[rt<<1].rm;}int query(int q,int rt,int s,int e){    //到達葉子節點或是當前節點為空白或為滿的情況,直接返回。    if(s==e || tre[rt].sm==0 || tre[rt].sm==tre[rt].r-tre[rt].l+1)        return tre[rt].sm;    int m=(s+e)>>1;    if(q<=m)    {        //若是在做孩子的右連續區間,那麼還要看右孩子的左連續區間        if(q>=tre[rt<<1].r-tre[rt<<1].rm+1)            return query(q,lson)+query(m+1,rson);        else            return query(q,lson);    }    else    {        //同理~        if(q<=tre[rt<<1|1].lm+tre[rt<<1|1].l-1)            return query(m,lson)+query(q,rson);        else            return query(q,rson);    }}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        int top=-1;        build(1,1,n);        for(int i=0;i<m;i++)        {            int x;            char str[5];            scanf("%s",str);            if(str[0]=='D')            {                scanf("%d",&x);                update(x,0,1,1,n);                st[++top]=x;            }            else if(str[0]=='R')            {                int y=st[top--];                if(top>=-1)                    update(y,1,1,1,n);            }            else if(str[0]=='Q')            {                scanf("%d",&x);                int k=query(x,1,1,n);                printf("%d\n",k);            }        }    }    return 0;}




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.