HDU-1540 Tunnel Warfare ,线段树,找最长区间

断断续续写了三天
坑点的话,一个村庄被摧毁多次,用栈保存的话,重建的时候要进行判断

杭电习惯坑,实际每次有多组数据,记得memset
询问有点难度吧,就是找到你的村庄,然后左右查找能延伸多远
代码如下,已AC
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include<cstdio>
#include<cmath>


using namespace std;

stack<int>A;
struct nod{
    int l,r;//记录一个区间内,从左数和从右数最长连续

}node[200000];

void build(int l,int r,int p){
    if(l==r){
        node[p].l=1;
        node[p].r=1;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,p<<1);
    build(mid+1,r,(p<<1)+1);
    node[p].l=node[p].r=node[p<<1].r+node[(p<<1)+1].l;



}

void dest(int l,int r,int p,int c){
    //printf("* ");
    if(l==r&&l==c){
        node[p].l=0;
        node[p].r=0;
        return ;
    }
    int mid=(l+r)/2;
    if(mid>=c)
        dest(l,mid,p<<1,c);
    if(c>mid)
        dest(mid+1,r,(p<<1)+1,c);
    if(node[(p<<1)+1].l==r-mid)//这里卡了好久,后来发现了,之前错在去判断l和r是否相等
        node[p].r=node[p<<1].r+node[(p<<1)+1].l;
     else
        node[p].r=node[(p<<1)+1].r;
     if(node[p<<1].l==mid-l+1)
        node[p].l=node[p<<1].l+node[(p<<1)+1].l;
    else
        node[p].l=node[p<<1].l;

}
void rebulit(int l,int r,int p,int c){//毁灭和重建可以合起来写,懒得改了
    if(l==r&&l==c){
        node[p].l=1;
        node[p].r=1;
        return ;
    }
    int mid=(l+r)/2;
   if(mid>=c)
        rebulit(l,mid,p<<1,c);
    if(c>mid)
        rebulit(mid+1,r,(p<<1)+1,c);
   if(node[(p<<1)+1].l==r-mid)
        node[p].r=node[p<<1].r+node[(p<<1)+1].l;
     else
        node[p].r=node[(p<<1)+1].r;
     if(node[p<<1].l==mid-l+1)
        node[p].l=node[p<<1].l+node[(p<<1)+1].l;
    else
        node[p].l=node[p<<1].l;



}
int ans=0;
int ll=0,rr=0;
void query(int l,int r,int p,int c){
   int mid =(l+r)/2;
   if(l==r){
    if(node[p].l)
        ll=rr=1;
    else
        ll=rr=0;
    ans=node[p].l;
    return ;
   }
   if(c<=mid){
        query(l,mid,p<<1,c);
        if(rr)
            ans+=node[(p<<1)+1].l;
        if(node[(p<<1)+1].l<r-mid) rr=0;
   }
  else{
    query(mid+1,r,(p<<1)+1,c);
    if(ll)
        ans+=node[p<<1].r;
    if(node[p<<1].r<mid-l+1) ll=0;
   }

}


int main()
{
   int n,m,w;
   char c;
   int haha[100000]={0};
  while(~scanf("%d%d",&n,&m)){
    ans=0;ll=0;rr=0;
    for(int i=0;i<200000;i++){
        node[i].l=node[i].r=0;
    }
    while(!A.empty()) A.pop();
    build(1,n,1);
//    for(int i=0;i<20;i++)
//                        printf("%d %d\n",node[i].l,node[i].r);
       for(int i=0;i<m;i++){
            getchar();
            scanf("%c",&c);
            if(c=='R'){
                if(A.empty())
                    break;
                while(!A.empty()){
                int num=A.top();
                A.pop();
                    if(haha[num]==1){
                        haha[num]=0;
                        rebulit(1,n,1,num);
                        break;
                    }
                }
            }
            else{
                scanf("%d",&w);
                if(c=='D'){
                    haha[w]=1;
                    A.push(w);
               //     printf("=====");
                    dest(1,n,1,w);

                }
                if(c=='Q'){
                    query(1,n,1,w);
                    printf("%d\n",ans);
                }
            }
                                for(int i=0;i<20;i++)
              printf("%d %d\n",node[i].l,node[i].r);
   }
  }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41758381/article/details/80041589